AsyncTask是一种轻量级的异步任务类,在线程池中执行后台,然后通知主线程更新UI。其实AsyncTask封装了线程池和Handler。但是AsyncTask不适合进行特别耗时的操作,因为在Android 3.0以后,AsyncTask是串行执行,相当于是在内部的单线程运行。
首先,AsyncTask是一个抽象类,有三个泛型参数,分别是Params,Progress,Result,他们代表的含义是输入的参数,后台执行任务时的速度类型,任务结束返回的类型。
public abstract class AsyncTask<Params, Progress, Result> {}
其中,AsyncTask有四个很重要的方法
- doInBackground(),在线程池中执行的耗时异步操作
- onPreExecute(),在主线程中执行,异步任务操作之前执行,做一些准备工作
- onPostExecute(),也是在主线程中执行,异步任务操作完成之后执行的
- onProgressUpdate(),主线程中执行,异步任务进展的速度。但是需要在doInBackground()方法里面调用publishProgress(Progress p)才可以调用,我们下面用代码来验证以上的说法。
class MyAsyncTask1 extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
Log.i(TAG,"doInBackground(),当前线程:" + Thread.currentThread().getName() );
return null;
}
@Override
protected void onPreExecute() {
Log.i(TAG,"onPreExecute(),当前线程:" + Thread.currentThread().getName() );
}
@Override
protected void onPostExecute(Void aVoid) {
Log.i(TAG,"onPostExecute(),当前线程:" + Thread.currentThread().getName() );
}
@Override
protected void onProgressUpdate(Void... values) {
Log.i(TAG,"onProgressUpdate(),当前线程:" + Thread.currentThread().getName() );
}
}
不要忘记了在主线程里面new MyAsyncTask1().execute();
首先执行的是onPreExecute,接着是doInBackground(),最后是onPostExecute(),接着在doInBackground()里面添加publishProgress()方法。
我们现在模拟一个下载进度条的异步任务
class MyAsync extends AsyncTask<Void,Integer,Void>{
@Override
protected Void doInBackground(Void... params) {
//模拟下载过程
for (int i = 1;i<=100;i++){
if (isCancelled()){
break;
}
//提示进度条现在的情况
publishProgress(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPreExecute() {
//设置进度条初始值
pg.setProgress(0);
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
@Override
protected void onProgressUpdate(Integer... values) {
if (isCancelled()){
return;
}
//当前进度情况
pg.setProgress(values[0]);
}
}