AsyncTask是一个抽象类,其中重要的属性有以下几个:
THREAD_POOL_EXECUTOR:一个Executor对象,AsyncTask内部也是定义了一个线程池对象,真正的执行任务的地方
mWorker :定义了在子线程中执行的回调
SERIAL_EXECUTOR:一个有序的Executor对象,内部存储了一个任务的队列,串行执行Runnable
mFuture:作为一个线程池处理的任务对象,能够提供结果的回调
sHandler:作为子线程到主线程之间的数据通信
下面对常见用法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 主要用来处理多线程中传递数据的问题,
调用的流程解析:
AsyncTask.execute()--->AsyncTask.executeOnExecutor()--->AsyncTask.onPreExecute()--->sDefaultExecutor.execute(mFuture)
sDefaultExecutor.execute(mFuture)执行的时候源码如下:
每个runnable都会先保存在mTasks中,第一次mActive为null,执行scheduleNext()方法,取出mTasks中的Runnable,赋值给mActive,将使用THREAD_POOL_EXECUTOR对象进行执行传入的Runnable,线程池启动一个线程以后调用mActive的run方法,也就是
注意这里会继续检测mTasks中有没有任务,有就继续执行,会全部都放入线程池中执行。这里传入的r的参数就是前面构造器中赋值的mFuture,mFuture继承FutureTask,它们实现了Runnable, Future两个接口,mFuture调用run方法,此时已经是处于子线程中了
这里有个callable对象,该对象是FutureTask的构造方法中传入的,在AsyncTask的构造方法中,定义mFuture对象时,传入了mWork对象,这里会调用mWork.call()方法,此时还是在子线程中,调用方法AsyncTask.doInBackground(),这是一个抽象方法,这里是在子线程中,于是就完成了在子线程中使用doInBackground方法,并提供了一个返回值result。
子线程中的任务已经完成,并且返回结果为result,这时候需要返回结果给主线程使用,执行postResult方法,使用handler机制,这里的handle对象是构造方法中定义的。发送消息传递了对象AsyncTaskResult,该对象中保存了子线程处理的结果。
handle对象为InternalHandler,在AsyncTask中的内部定义的,这里就已经切换回到主线程中,又调用了AsyncTask.onProgressUpdate()和AsyncTask.finish(),完成了主线程的回调。
总结:AsyncTask的调用原理,使用了线程池完成后台任务,使用FutureTask作为传递给线程执行的任务并能返回执行的结果,子线程中执行超时任务,取得结果后使用handler进行线程之间数据的传递,完成所有的操作。