最近看了Android 多线程:AsyncTask的原理 及其源码分析 这篇文章,对AsyncTask的原理和源码方面的知识有了较为清晰的认识,不过在看文章过程中还是遇到有些部分无法连贯起来,后面自己翻了翻源码,在这里做一个补充
先介绍一下AsyncTask创建实例时源码中的一些方法和处理
/*** Creates a new asynchronous task. This constructor must be invoked on the UI thread.** @hide*/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 uncheckedresult = doInBackground(mParams);Binder.flushPendingCommands();} catch (Throwable tr) {mCancelled.set(true);throw tr;} finally {postResult(result);}return result;}};mFuture = new FutureTask<Result>(mWorker) {@Overrideprotected 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);}}};}
如上代码所示,创建了一个WorkRunnable的实例mWorker, 在他的Call()方法回调中处理doInBackground()的耗时操作,接着又将mWorker作为参数传入了FutureTask中,他的实例是mFuture
然后从mTask.execute();开始,这句就是开启AsyncTask的执行了
看下源码
public final AsyncTask<Params, Progress, Result> execute(Params... params) {return executeOnExecutor(sDefaultExecutor, params);}
在源码中此方法调用了 executeOnExecutor(sDefaultExecutor, params);方法
再看看executeOnExecutor的源码
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;}
在这个方法中最重要一句就是exec.execute(mFuture);这里的exec就是sDefaultExecutor,我们接着查找sDefaultExecutor的来源,可以找到如下两句
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
很明显我们接着要找到SerialExecutor这个内部类,源码如下
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);}}}
根据前面的exec.execute(mFuture)就可以知道源码中的r.run()方法其实就是mFuture.run(),我们接着去FutureTask类的源码中到这个方法
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 interruptsint s = state;if (s >= INTERRUPTING)handlePossibleCancellationInterrupt(s);}}
可以看到try catch方法中调用了c.call(),而c是全局变量callable赋值而来,这个callable追溯上去便是FutureTask创建实例时从外部传入的参数,即一开始说的WorkerRunnable实例mWorker,所以此处便是调用了mWorker.call()方法,在call()方法中调用doInBackground()处理耗时操作,这样整个异步处理的源码分析就能贯通起来了
写的匆忙,如有遗漏和错误之处请指正,谢谢!