赞
踩
(一)介绍
1,AsyncTask,是一种轻量级的异步任务类,内部封装了Handler和Thread,可以方便的将子线程的数据传递到UI线程并更新UI.但它不适合进行特别耗时的任务,对于特别耗时的任务,建议使用线程池.
(一)关键api
1,三个参数:Params,Progress,Result,如果AsyncTask确定不需要传递具体参数,那么这三个泛型参数可以用Void来代替。
A,Params,表示参数的类型
B,Progress,表示后台任务执行的进度的类型
C,Result,后台任务返回结果的类型
2,四个参数:
onPreExcute(),DoInBackGround(),onProgressUpdate(),onPostExcute();
A,onPreExcute(),在主线程中执行,在异步任务之前调用,一般可以用于做任务前的准备,比如进度圈的显示.
B,DoInBackGround(),在线程池中执行,用于处理一些耗时任务.通过publishProgress()将进度发布出去.然后通过return将结果返回出去.
C,onProgressUpdate(),在主线程中执行,获取任务的最新进度.
D,onPostExcute(),在主线程中执行,用于接收异步任务的结果.
E,onCancelled(),它同样在主线程中执行,当异步任务取消时,onCancelled()会被调用,这个时候onPostExecute()则不会被调用,但是要注意的是,AsyncTask中的cancel()方法并不是真正去取消任务,只是设置这个任务为取消状态,我们需要在doInBackground()判断终止任务。就好比想要终止一个线程,调用interrupt()方法,只是进行标记为中断,需要在线程内部进行标记判断然后中断线程。
)
(三)代码使用:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressDialog = new ProgressDialog(this);
new DownloadTask().execute();
}
class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
@Override
protected void onPreExecute() {
mProgressDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
while (true) {
int downloadPercent = doDownload();
publishProgress(downloadPercent);
if (downloadPercent >= 100) {
break;
}
}
} catch (Exception e) {
return false;
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values) {
mProgressDialog.setMessage("当前下载进度:" + values[0] + "%");
}
@Override
protected void onPostExecute(Boolean result) {
mProgressDialog.dismiss();
if (result) {
Toast.makeText(ActivityA.this, "下载成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ActivityA.this, "下载失败", Toast.LENGTH_SHORT).show();
}
}
}
(四)注意事项:
1,一个AsyncTask对象只能创建一次,也就是说只能调用一次excute()方法,否则会报运行时异常.
2,AsyncTask必须在主线程中创建,在主线程中加载.
(五)弊端:
1,生命周期
AsyncTask不与任何组件绑定生命周期,所以在Activity/或者Fragment中创建执行AsyncTask时,最好在Activity/Fragment的onDestory()调用 cancel(boolean);
2.内存泄漏
如果AsyncTask被声明为Activity的非静态的内部类,那么AsyncTask会保留一个对创建了AsyncTask的Activity的引用。如果Activity已经被销毁,AsyncTask的后台线程还在执行,它将继续在内存里保留这个引用,导致Activity无法被回收,引起内存泄露。
3. 结果丢失
屏幕旋转或Activity在后台被系统杀掉等情况会导致Activity的重新创建,之前运行的AsyncTask(非静态的内部类)会持有一个之前Activity的引用,这个引用已经无效,这时调用onPostExecute()再去更新界面将不再生效。
(六),原理
Android3.0开始,AsyncTask默认采用串行执行.若是想并行执行,只需调用executeOnExecutor方法,并传入THREAD_POOL_EXECUTOR作为其线程池即可。(在不同版本的模拟器就可以测出)
AsyncTask有2个线程池:SerialExcutor和THREAD_POOL_EXCUTOR,SerialExcutor是用于排队的,而THREAD_POOL_EXCUTOR才是真正执行任务的.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。