(转载)再谈Android AsyncTask
原文地址:再谈Android AsyncTask的优缺点 - 程小白 - 博客园
1、Asynctask简介
1.1 使用方法简介
Asynctask作为Android的基础之一,怎么使用就不多讲解了,网上到处都是教程,建议查看Android官方API文档:https://developer.android.google.cn/reference/android/os/AsyncTask.html
Asynctask的实现:
private class IAsyncTask extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... args1) {
Log.i(TAG, "doInBackground in:" + args1[0]);
int times = 10;
for (int i = 0; i < times; i++) {
publishProgress(i);//提交之后,会执行onProcessUpdate方法
}
Log.i(TAG, "doInBackground out");
return "over";
}
/**
* 在调用cancel方法后会执行到这里
*/
protected void onCancelled() {
Log.i(TAG, "onCancelled");
}
/**
* 在doInbackground之后执行
*/
protected void onPostExecute(String args3) {
Log.i(TAG, "onPostExecute:" + args3);
}
/**
* 在doInBackground之前执行
*/
@Override
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
/**
* 特别赞一下这个多次参数的方法,特别方便
* @param args2
*/
@Override
protected void onProgressUpdate(Integer... args2) {
Log.i(TAG, "onProgressUpdate:" + args2[0]);
}
}
使用方法如下:
mBtnSyncTask.setOnClickListener(new View.OnClickListener() {
@Override
publicvoid onClick(View v) {
newIAsyncTask().execute("yanlog test");
}
});
1.2 Android 内部源码实现
关于Handler+Message+Message Queue+Looper的实现就不介绍了,老生常谈了。所以下面主要看一下AsyncTask的源码实现:
AsyncTask的核心方法应该是
public final AsyncTask<Params, Progress, Result> execute(Params... params)
那我们就看下当调用了execute方法后,都发生了什么,下面是执行的序列图。
AsyncTask调用流程通过上述流程,结合源码部分,我们知道,关键的点是4个成员:
1. 线程池
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
public static final ExecutorTHREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor =new ThreadPoolExecutor(
CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue,sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
创建了线程池,该线程池用以实现线程的调度运行,全进程只有一个实例,可以理解为单例实现。
2. Callable实现WorkRunnable类成员变量mWorker
private final WorkerRunnable<Params, Result> mWorker;
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
private static abstract class WorkerRunnable implements Callable {
Params[] mParams;
}
是一个Callable实现,从这里可知,实际是内部通过Future来实现的Callable调用。
3. FutureTask成员变量mFuture
private final FutureTask mFuture;
mFuture = new FutureTask(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
}catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
}catch (ExecutionExceptione) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
}catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
这里可以发现,实际是通过FutureTask来封装了mWorker,即Callable对象。再通过Executor线程池来完成FutureTask的调度运行。此时基于FutureTask的特性,mWorker即Callable的call方法会在FutureTask的run方法中被调用。
在FutureTask的结束事件时会调用finishCompletion()再调用方法done(),即向主线程的Handler消息队列中来发送结果消息。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult(this, result));
message.sendToTarget();
return result;
}
此时,AsyncTaskResult就是最终的结果封装了。