AsyncTask是Android提供的轻量级的异步类,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。

AsyncTask定义了三种泛型类型 Params,Progress和Result。

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。
例如:
class RetrieveCategoryTask extends AsyncTask<String, Void, List<String>>

根据AsyncTask源码:

public abstract class AsyncTask<Params, Progress, Result> 

这里的String, Void, List<String>分别对应Params, Progress, Result


一般使用AsyncTask至少需要实现以下2个方法:
protected abstract Result doInBackground(Params... var1);//耗时操作,例如网络请求任务。这里相当于一个子线程

   protected void onPostExecute(Result result) {//可以在这里处理doInBackground得到的数据,能够对UI进行操作,属于UI主线程throw new RuntimeException("Stub!");}

当然如果有必要的话还可以实现下面几个方法:

  • onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
  • onPreExecute()        这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled()             用户调用取消时,会调用此方法

使用AsyncTask类,以下是几条必须遵守的准则:

  • Task的实例必须在UI thread中创建;
  • execute方法必须在UI thread中调用;
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
  • 该task只能被执行一次,否则多次调用时将会出现异常;

需要注意的是Android为了安全考虑,不允许在主线程即UI线程进行耗时操作。例如HTTP请求等。

如果在UI中使用了耗时操作的话,Android Studio本身是不会报错的。只有在APP执行到相应的耗时操作位置时才会停止运行。手机或模拟器上会出现“很抱歉,XXX已停止运行”同时Android Studio logcat输出“

E/AndroidRuntime: FATAL EXCEPTION: main
Process:.....

java.lang.RuntimeException.....

下面给出一个范例:

  1 package idv.ron.texttojson_android;
  2
  3 import android.app.ProgressDialog;
  4 import android.content.Context;
  5 import android.net.ConnectivityManager;
  6 import android.net.NetworkInfo;
  7 import android.os.AsyncTask;
  8 import android.os.Bundle;
  9 import android.support.v7.app.ActionBarActivity;
 10 import android.util.Log;
 11 import android.view.LayoutInflater;
 12 import android.view.View;
 13 import android.view.ViewGroup;
 14 import android.widget.AdapterView;
 15 import android.widget.AdapterView.OnItemClickListener;
 16 import android.widget.ArrayAdapter;
 17 import android.widget.BaseAdapter;
 18 import android.widget.ListView;
 19 import android.widget.Spinner;
 20 import android.widget.TextView;
 21 import android.widget.Toast;
 22
 23 import com.google.gson.Gson;
 24 import com.google.gson.JsonObject;
 25 import com.google.gson.reflect.TypeToken;
 26
 27 import java.io.BufferedReader;
 28 import java.io.BufferedWriter;
 29 import java.io.IOException;
 30 import java.io.InputStreamReader;
 31 import java.io.OutputStreamWriter;
 32 import java.lang.reflect.Type;
 33 import java.net.HttpURLConnection;
 34 import java.net.URL;
 35 import java.util.List;
 36
 37 public class SearchActivity extends ActionBarActivity {
 38     private final static String TAG = "SearchActivity";
 39     private ProgressDialog progressDialog;
 40     private AsyncTask retrieveCategoryTask, retrieveBookTask;
 41     private Spinner spCategory;
 42     private ListView lvBook;
 43
 44     class RetrieveCategoryTask extends AsyncTask<String, Void, List<String>> {
 45         @Override
 46         protected void onPreExecute() {
 47             super.onPreExecute();
 48             progressDialog = new ProgressDialog(SearchActivity.this);
 49             progressDialog.setMessage("Loading...");
 50             progressDialog.show();
 51         }
 52
 53         @Override
 54         protected List<String> doInBackground(String... params) {
 55             String url = params[0];
 56             String jsonIn;
 57             JsonObject jsonObject = new JsonObject();
 58             jsonObject.addProperty("param", "category");
 59             try {
 60                 jsonIn = getRemoteData(url, jsonObject.toString());
 61             } catch (IOException e) {
 62                 Log.e(TAG, e.toString());
 63                 return null;
 64             }
 65
 66             Gson gson = new Gson();
 67             Type listType = new TypeToken<List<String>>() {
 68             }.getType();
 69
 70             return gson.fromJson(jsonIn, listType);
 71         }
 72
 73         @Override
 74         protected void onPostExecute(List<String> items) {
 75             ArrayAdapter<String> adapter = new ArrayAdapter<>(SearchActivity.this,
 76                     android.R.layout.simple_list_item_1, items);
 77             adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 78             spCategory.setAdapter(adapter);
 79             progressDialog.cancel();
 80         }
 81     }
 82
 83     public class RetrieveBookTask extends
 84             AsyncTask<String, Integer, List<Book>> {
 85         @Override
 86         protected void onPreExecute() {
 87             super.onPreExecute();
 88             progressDialog = new ProgressDialog(SearchActivity.this);
 89             progressDialog.setMessage("Loading...");
 90             progressDialog.show();
 91         }
 92
 93         @Override
 94         protected List<Book> doInBackground(String... params) {
 95             String url = params[0];
 96             String category = params[1];
 97             String jsonIn;
 98             JsonObject jsonObject = new JsonObject();
 99             jsonObject.addProperty("param", category);
100             try {
101                 jsonIn = getRemoteData(url, jsonObject.toString());
102             } catch (IOException e) {
103                 Log.e(TAG, e.toString());
104                 return null;
105             }
106
107             Gson gson = new Gson();
108             Type listType = new TypeToken<List<Book>>() {
109             }.getType();
110             return gson.fromJson(jsonIn, listType);
111         }
112
113         @Override
114         protected void onPostExecute(List<Book> result) {
115             showResult(result);
116             progressDialog.cancel();
117         }
118     }
119
120     @Override
121     protected void onCreate(Bundle savedInstanceState) {
122         super.onCreate(savedInstanceState);
123         setContentView(R.layout.search_activity);
124         spCategory = (Spinner) findViewById(R.id.spCategory);
125         lvBook = (ListView) findViewById(R.id.lvBook);
126         if (networkConnected()) {
127             retrieveCategoryTask = new RetrieveCategoryTask().execute(Common.URL);
128         } else {
129             showToast(this, R.string.msg_NoNetwork);
130         }
131     }
132
133     // check if the device connect to the network
134     private boolean networkConnected() {
135         ConnectivityManager conManager =
136                 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
137         NetworkInfo networkInfo = conManager.getActiveNetworkInfo();
138         return networkInfo != null && networkInfo.isConnected();
139     }
140
141
142     private String getRemoteData(String url, String jsonOut) throws IOException {
143         StringBuilder jsonIn = new StringBuilder();
144         HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
145         connection.setDoInput(true); // allow inputs
146         connection.setDoOutput(true); // allow outputs
147         connection.setUseCaches(false); // do not use a cached copy
148         connection.setRequestMethod("POST");
149         connection.setRequestProperty("charset", "UTF-8");
150         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
151         bw.write(jsonOut);
152         Log.d(TAG, "jsonOut: " + jsonOut);
153         bw.close();
154
155         int responseCode = connection.getResponseCode();
156
157         if (responseCode == 200) {
158             BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
159             String line;
160             while ((line = br.readLine()) != null) {
161                 jsonIn.append(line);
162             }
163         } else {
164             Log.d(TAG, "response code: " + responseCode);
165         }
166         connection.disconnect();
167         Log.d(TAG, "jsonIn: " + jsonIn);
168         return jsonIn.toString();
169     }
170
171     public void onSearchClick(View v) {
172         Object item = spCategory.getSelectedItem();
173         if (item == null || item.toString().trim().length() <= 0) {
174             showToast(this, R.string.msg_NoCategoryFound);
175         } else {
176             String category = item.toString().trim();
177             if (networkConnected()) {
178                 retrieveBookTask = new RetrieveBookTask().execute(Common.URL, category);
179             } else {
180                 showToast(this, R.string.msg_NoNetwork);
181             }
182         }
183     }
184
185     public void showResult(List<Book> result) {
186         final BookListAdapter adapter = new BookListAdapter(this, result);
187         lvBook.setAdapter(adapter);
188         lvBook.setOnItemClickListener(new OnItemClickListener() {
189             @Override
190             public void onItemClick(AdapterView<?> parent, View view,
191                                     int position, long id) {
192                 adapter.expand(position);
193                 lvBook.setItemChecked(position, true);
194             }
195         });
196     }
197
198     private class BookListAdapter extends BaseAdapter {
199         private LayoutInflater layoutInflater;
200         private List<Book> bookList;
201         private boolean[] bookDetailExpanded;
202
203         public BookListAdapter(Context context, List<Book> bookList) {
204             this.layoutInflater = LayoutInflater.from(context);
205             this.bookList = bookList;
206             this.bookDetailExpanded = new boolean[bookList.size()];
207         }
208
209         @Override
210         public int getCount() {
211             return bookList.size();
212         }
213
214         @Override
215         public Object getItem(int position) {
216             return bookList.get(position);
217         }
218
219         @Override
220         public long getItemId(int position) {
221             return bookList.get(position).getId();
222         }
223
224         @Override
225         public View getView(int position, View convertView, ViewGroup parent) {
226             if (convertView == null) {
227                 convertView = layoutInflater.inflate(
228                         R.layout.book_listview_item, parent, false);
229             }
230             TextView tvBookTitle = (TextView) convertView
231                     .findViewById(R.id.tvBookTitle);
232             TextView tvBookDetail = (TextView) convertView
233                     .findViewById(R.id.tvBookDetail);
234             Book book = bookList.get(position);
235
236             tvBookTitle.setText(book.getName() + "  $" + book.getPrice());
237             tvBookDetail.setText("Author: " + book.getAuthor() + "  Type: "
238                     + book.getType());
239             tvBookDetail
240                     .setVisibility(bookDetailExpanded[position] ? View.VISIBLE
241                             : View.GONE);
242             return convertView;
243         }
244
245         public void expand(int position) {
246             // 被點擊的資料列才會彈出內容,其他資料列的內容會自動縮起來
247             // for (int i=0; i<newsExpanded.length; i++) {
248             // newsExpanded[i] = false;
249             // }
250             // newsExpanded[position] = true;
251
252             bookDetailExpanded[position] = !bookDetailExpanded[position];
253             notifyDataSetChanged();
254         }
255
256     }
257
258     @Override
259     protected void onPause() {
260         if (retrieveCategoryTask != null) {
261             retrieveCategoryTask.cancel(true);
262             retrieveCategoryTask = null;
263         }
264
265         if (retrieveBookTask != null) {
266             retrieveBookTask.cancel(true);
267             retrieveBookTask = null;
268         }
269
270         super.onPause();
271     }
272
273     private void showToast(Context context, int messageId) {
274         Toast.makeText(context, messageId, Toast.LENGTH_SHORT).show();
275     }
276 }

转载于:https://www.cnblogs.com/Linccy/p/5648540.html

Android AsyncTask 详解及注意事项相关推荐

  1. Android AsyncTask详解

    前言 一提到多线程,我们不得不提到AsyncTask,很多Android开发人员在网络请求这块,一般会使用开源框架,比如Volley,Okhttp,retrofit等.但是有一部分人,比较忠于封装As ...

  2. [Android] AsyncTask详解

    2019独角兽企业重金招聘Python工程师标准>>> 本篇随笔将讲解一下Android的多线程的知识,以及如何通过AsyncTask机制来实现线程之间的通信. 一.Android当 ...

  3. 【转】Android菜单详解——理解android中的Menu--不错

    原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...

  4. Android菜单详解——理解android中的Menu

    前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...

  5. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  6. Android LayoutInflater详解

    Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...

  7. android Fragments详解

    android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...

  8. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

  9. android WebView详解,常见漏洞详解和安全源码(上)

    这篇博客主要来介绍 WebView 的相关使用方法,常见的几个漏洞,开发中可能遇到的坑和最后解决相应漏洞的源码,以及针对该源码的解析.  由于博客内容长度,这次将分为上下两篇,上篇详解 WebView ...

最新文章

  1. iOS底层原理 - 常驻线程
  2. pr预设的卷及内核锐化是什么_看完这一篇,彻底搞懂锐化怎么用!
  3. [Bug] .NET 2.0 的Bug —— ComboBox中不能添加Component.
  4. [Redux/Mobx] redux和flux的区别是什么?
  5. Linux基础(2)-基础命令和bash的基础特性(1)
  6. FE.ES-理解Event Loop
  7. jacob 详解 语音_JAVA 实现Jacob语音播报
  8. C++ 引用 支持多级嵌套吗
  9. Linux 性能分析工具
  10. 诗与远方:无题(九十六)- 空人空心
  11. Mac常见问题:如何使用文件保险箱加密 Mac 上的启动磁盘!
  12. 几款接口文档管理工具
  13. 读书笔记—CLR via C#章节4-7
  14. linux mint 解压zip,Linux:压缩解压
  15. 直方图均衡化背后的数学
  16. C语言求一元二次方程根
  17. GD图片处理——缩放、剪切、相框、水印、锐化、旋转、翻转、透明度、反色
  18. DDPG中的Ornstein-Uhlenbeck过程怎么理解
  19. Pytorch学习(三)Linear层
  20. 网上商城订货系统解决批发商管理痛点

热门文章

  1. html5画直线,小白学canvas-从0到1,画直线
  2. java对象命名用变量_在Java语言中,所有的变量、常量、对象和类都是用【 】来命名的。...
  3. File转换成MultiPartFile
  4. CyclicBarrier(栅栏)实现高并发测试
  5. CSS中给表格的第一列及最后一列设置不同的样式
  6. 【搞事情】英文文档单词对比自动翻译
  7. CSS→代码语法、优先级、选择器、权值、字体文本、颜色、长度值、块状内联元素、盒模型、布局模型→层模型绝对相对定位、div排列、水平居中
  8. php 批量删除挂马文件夹,PHP批量挂马脚本
  9. LuaForUnity5:Lua的字符串
  10. Unity3D基础10:利用Transform组件移动物体