1、AsyncTask是一个抽象类,其中重要的属性有以下几个:
THREAD_POOL_EXECUTOR:一个Executor对象,AsyncTask内部也是定义了一个线程池对象,真正的执行任务的地方
mWorker :定义了在子线程中执行的回调
SERIAL_EXECUTOR:一个有序的Executor对象,内部存储了一个任务的队列,串行执行Runnable
mFuture:作为一个线程池处理的任务对象,能够提供结果的回调
sHandler:作为子线程到主线程之间的数据通信
2、下面对常见用法AsyncTask.execute()做代码跟踪
AsyncTask的构造函数中
public AsyncTask(@Nullable Looper callbackLooper) {
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
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;
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
上面构造方法中,定义了mHandler ,mWorker对象和mFuture对象,mHandler 主要用来处理多线程中传递数据的问题。
execute()前部分调用的流程解析
AsyncTask.execute()--->AsyncTask.executeOnExecutor()--->AsyncTask.onPreExecute()--->sDefaultExecutor.execute(mFuture)
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
继续调用executeOnExecutor(),这里传入了参数sDefaultExecutor,系统默认设置值为SerialExecutor对象,SerialExecutor后面分析。
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
上面调用了onPreExecute();这个就是留给用户调用的方法,继续调用exec.execute(mFuture);exec是前面传入的SerialExecutor对象;mFuture是构造方法中定义的Future对象。
下面接着看SerialExecutor中的execute()
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
在SerialExecutor 中定义了一个ArrayDeque对象,ArrayDeque是双端队列,具有先进先出或后进先出的特点,底层使用的是数组存储元素,这里的元素是Runnable对象。前面调用execute()方法,传入的是mFuture对象,先创建一个Runnable对象,存入到双端队列mTasks 中,第一次mActive 为null,调用scheduleNext(),再将mTasks中存入的元素取出来赋值给的mActive 并调用线程池THREAD_POOL_EXECUTOR进行执行。赋值给mActive 是为了不让多任务情况下同步执行,这里就决定了不能同步多任务执行的情况。
THREAD_POOL_EXECUTOR是一个线程池对象:
public static final Executor THREAD_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;
}
线程执行任务会调用mFuture的run()方法,mFuture是FutureTask对象,实现了Runnable, Future接口
public void run() {
if (state != NEW ||
!U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
这里重点调用 result = c.call();c对象是FutureTask的构造方法中进行的赋值,传入的是AsyncTask构造方法中的mWorker对象,继续调用mWorker的call方法,先跳过mWorker的执行call(),将执行的结果传入set(result),setf方法会将结果保存在成员变量outcome中留待后面取出;
set(result)---> finishCompletion();--->done();
finishCompletion()方法中会删除所有的等待的线程。done()方法是AsyncTask构造方法mFuture定义复写父类的方法。
done()--->postResultIfNotInvoked(get());--->postResult(result);
get()方法会取得FutureTask的run()执行的结果outcome。
postResult(result);这一步已经是取得了子线程执行的结果,下一步需要将结果传递给主线程,系统采用的是handler的方法进行数据的传递。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
1)getHandler()取得是mHandler,是在AsyncTask的构造方法中定义的,mHandler由构造方法中传入的参数决定是属于哪一个线程的循环器,默认使用的是主线程的循环器,所以mHandler默认是属于子线程。
private static Handler getMainHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler(Looper.getMainLooper());
}
return sHandler;
}
}
2)对结果进行了封装,封装结果为AsyncTaskResult对象,并进行了传递。
现在是主线程中处理最后的结果
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
这里按照不同情况处理最后的结果调用了AsyncTask的finish方法或者onProgressUpdate方法。
到这里就已经结束了整体的大概流程的分析。现在前面还留有一个mWork的call的方法调用,在AsyncTask的构造方法中
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;
}
};
在调用到这里的时候,已经是在子线程中了,先调用了doInBackground(mParams)方法,这就是留给用户自己实现的方法,在子线程中处理相关事项。并调用了 postResult(result);通知主线程。
至于MESSAGE_POST_PROGRESS的处理情况,一般是用户在doInBackground中主动去调用publishProgress(Progress... values)方法才可以。
总结:大概的流程分析就这样,具体的细节还得自己去分析,总体上AsyncTask使用了线程池开启子线程处理后台任务,然后使用了Handler进行子线程和主线程之间的数据传递问题。