[转载]AsyncTask源码分析 – 周柯文 – 博客园.
要研究Android的AsyncTask之前,要先搞明白FutureTask和Executor类:
FutureTask是什么:
FutureTask实际上是一个任务的操作类,它并不启动新线程,只是在自己所在线程上操作,任务的具体实现是构造FutureTask时提供的,实现自Callable<V>接口,FutureTask不知道具体的任务是什么,它只知道如何调度任务,如:
- 如何启动任务:在FutureTask的run()方法中(实现自Runnable.run()),调用Callable.call()方法来启动任务,Callable.call()方法中是任务的具体实现;
- 如何取消任务:在cancel()里,中断执行任务的线程,记录任务结束状态,并调用done()方法来执行用户实现的操作;
- 如何返回任务的运行结果:如果任务还在执行,则阻塞线程(使用LockSupport.park()),直到任务结束才返回结果,用户可以通过get()方法来获取结果,同样当任务运行结束时,会调用down()来执行用户实现的操作。
使用FutureTask的好处是,更轻松的对任务进行管理,而不是像Runnable那样扔进线程后就啥也不能做了。
Executor是什么:
Executor顾名思义是任务执行者,它不关心是什么任务,只关心如何执行任务。Executor是个Interface,具体如何执行任务要看怎么实现这个接口,你可以这样实现:
class DirectExecutor implements Executor { @Override public void execute(Runnable r) { r.run(); } }
也可以这样实现:
class ThreadPerTaskExecutor implements Executor { @Override public void execute(Runnable r) { new Thread(r).start(); } }
这两种实现的区别显而易见,java文档还提供了另一个Executor实现的例子:
<span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >SerialExecutor</span><span class = "pln" > </span><span class = "kwd" > implements </span><span class = "pln" > </span><span class = "typ" >Executor</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >Queue</span><span class = "pln" > tasks </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >ArrayDeque</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >Executor</span><span class = "pln" > executor</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pln" > active</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "typ" >SerialExecutor</span><span class = "pun" >(</span><span class = "typ" >Executor</span><span class = "pln" > executor</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > this </span><span class = "pun" >.</span><span class = "pln" >executor </span><span class = "pun" >=</span><span class = "pln" > executor</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "lit" > @Override </span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > synchronized </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > execute</span><span class = "pun" >(</span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pln" > r</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > tasks</span><span class = "pun" >.</span><span class = "pln" >offer</span><span class = "pun" >(</span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > run</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > try </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > r</span><span class = "pun" >.</span><span class = "pln" >run</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > finally </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > scheduleNext</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >});</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >active </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > scheduleNext</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > protected </span><span class = "pln" > </span><span class = "kwd" > synchronized </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > scheduleNext</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >((</span><span class = "pln" >active </span><span class = "pun" >=</span><span class = "pln" > tasks</span><span class = "pun" >.</span><span class = "pln" >poll</span><span class = "pun" >())</span><span class = "pln" > </span><span class = "pun" >!=</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > executor</span><span class = "pun" >.</span><span class = "pln" >execute</span><span class = "pun" >(</span><span class = "pln" >active</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span> |
这个实现的意思是,严格按照用户提交的顺序来执行任务。Android的AsyncTask就使用了这个例子。
AsyncTask是如何实现的:
AsyncTask实现的关键地方在构造函数和executeOnExecutor()函数里。
- 首先看下构造函数:
<span class = "kwd" > public </span><span class = "pln" > </span><span class = "typ" >AsyncTask</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > mWorker </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >WorkerRunnable</span><span class = "pun" ><</span><span class = "typ" >Params</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Result</span><span class = "pun" >>()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "typ" >Result</span><span class = "pln" > call</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "kwd" > throws </span><span class = "pln" > </span><span class = "typ" >Exception</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > mTaskInvoked</span><span class = "pun" >.</span><span class = "kwd" >set</span><span class = "pun" >(</span><span class = "kwd" > true </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Process</span><span class = "pun" >.</span><span class = "pln" >setThreadPriority</span><span class = "pun" >(</span><span class = "typ" >Process</span><span class = "pun" >.</span><span class = "pln" >THREAD_PRIORITY_BACKGROUND</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "com" > //任务的具体实现</span><span class="pln"> </span><span class = "kwd" > return </span><span class = "pln" > postResult</span><span class = "pun" >(</span><span class = "pln" >doInBackground</span><span class = "pun" >(</span><span class = "pln" >mParams</span><span class = "pun" >));</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >};</span><span class = "pln" > mFuture </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >FutureTask</span><span class = "pun" ><</span><span class = "typ" >Result</span><span class = "pun" >>(</span><span class = "pln" >mWorker</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "lit" > @Override </span><span class = "pln" > </span><span class = "kwd" > protected </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > </span><span class = "kwd" >done</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > try </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > postResultIfNotInvoked</span><span class = "pun" >(</span><span class = "kwd" >get</span><span class = "pun" >());</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > catch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >InterruptedException</span><span class = "pln" > e</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >util</span><span class = "pun" >.</span><span class = "typ" >Log</span><span class = "pun" >.</span><span class = "pln" >w</span><span class = "pun" >(</span><span class = "pln" >LOG_TAG</span><span class = "pun" >,</span><span class = "pln" > e</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > catch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >ExecutionException</span><span class = "pln" > e</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > throw </span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >RuntimeException</span><span class = "pun" >(</span><span class = "pln" > </span><span class = "str" > "An error occured while executing doInBackground()" </span><span class = "pun" >,</span><span class = "pln" > e</span><span class = "pun" >.</span><span class = "pln" >getCause</span><span class = "pun" >());</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > catch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >CancellationException</span><span class = "pln" > e</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > postResultIfNotInvoked</span><span class = "pun" >(</span><span class = "kwd" > null </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >};</span><span class = "pln" > </span><span class = "pun" >}</span> |
代码中WorkerRunnable实现自Callable,所以mWorker就是任务的具体实现(call()中的doInBackground())。通过对FutureTask的说明可以知道,mFuture是mWorker的操作类,它不仅用来实现对AsyncTask任务的操作(cancel,get等),最主要的,实现了mWorker执行结束的操作:
<span class = "kwd" > private </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > postResultIfNotInvoked</span><span class = "pun" >(</span><span class = "typ" >Result</span><span class = "pln" > result</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "kwd" > boolean </span><span class = "pln" > wasTaskInvoked </span><span class = "pun" >=</span><span class = "pln" > mTaskInvoked</span><span class = "pun" >.</span><span class = "kwd" >get</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(!</span><span class = "pln" >wasTaskInvoked</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > postResult</span><span class = "pun" >(</span><span class = "pln" >result</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "typ" >Result</span><span class = "pln" > postResult</span><span class = "pun" >(</span><span class = "typ" >Result</span><span class = "pln" > result</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "lit" > @SuppressWarnings </span><span class = "pun" >(</span><span class = "str" > "unchecked" </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "typ" >Message</span><span class = "pln" > message </span><span class = "pun" >=</span><span class = "pln" > sHandler</span><span class = "pun" >.</span><span class = "pln" >obtainMessage</span><span class = "pun" >(</span><span class = "pln" >MESSAGE_POST_RESULT</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >AsyncTaskResult</span><span class = "pun" ><</span><span class = "typ" >Result</span><span class = "pun" >>(</span><span class = "kwd" > this </span><span class = "pun" >,</span><span class = "pln" > result</span><span class = "pun" >));</span><span class = "pln" > message</span><span class = "pun" >.</span><span class = "pln" >sendToTarget</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > result</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >InternalHandler</span><span class = "pln" > sHandler </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >InternalHandler</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >InternalHandler</span><span class = "pln" > </span><span class = "kwd" > extends </span><span class = "pln" > </span><span class = "typ" >Handler</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "lit" > @SuppressWarnings </span><span class = "pun" >({</span><span class = "pln" > </span><span class = "str" > "unchecked" </span><span class = "pun" >,</span><span class = "pln" > </span><span class = "str" > "RawUseOfParameterizedType" </span><span class = "pln" > </span><span class = "pun" >})</span><span class = "pln" > </span><span class = "lit" > @Override </span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > handleMessage</span><span class = "pun" >(</span><span class = "typ" >Message</span><span class = "pln" > msg</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >AsyncTaskResult</span><span class = "pln" > result </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >AsyncTaskResult</span><span class = "pun" >)</span><span class = "pln" > msg</span><span class = "pun" >.</span><span class = "pln" >obj</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > switch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >msg</span><span class = "pun" >.</span><span class = "pln" >what</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > case </span><span class = "pln" > MESSAGE_POST_RESULT</span><span class = "pun" >:</span><span class = "pln" > </span><span class = "com" > // There is only one result</span><span class="pln"> result</span><span class = "pun" >.</span><span class = "pln" >mTask</span><span class = "pun" >.</span><span class = "pln" >finish</span><span class = "pun" >(</span><span class = "pln" >result</span><span class = "pun" >.</span><span class = "pln" >mData</span><span class = "pun" >[</span><span class = "lit" > 0 </span><span class = "pun" >]);</span><span class = "pln" > </span><span class = "kwd" > break </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > case </span><span class = "pln" > MESSAGE_POST_PROGRESS</span><span class = "pun" >:</span><span class = "pln" > result</span><span class = "pun" >.</span><span class = "pln" >mTask</span><span class = "pun" >.</span><span class = "pln" >onProgressUpdate</span><span class = "pun" >(</span><span class = "pln" >result</span><span class = "pun" >.</span><span class = "pln" >mData</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > break </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > finish</span><span class = "pun" >(</span><span class = "typ" >Result</span><span class = "pln" > result</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >isCancelled</span><span class = "pun" >())</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > onCancelled</span><span class = "pun" >(</span><span class = "pln" >result</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > else </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > onPostExecute</span><span class = "pun" >(</span><span class = "pln" >result</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > mStatus </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Status</span><span class = "pun" >.</span><span class = "pln" >FINISHED</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span> |
FutureTask和Handler共同实现了任务结束的操作,代码很简单,不赘述。
接下来是executeOnExecutor()函数的实现:
<span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >AsyncTask</span><span class = "pun" ><</span><span class = "typ" >Params</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Progress</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Result</span><span class = "pun" >></span><span class = "pln" > execute</span><span class = "pun" >(</span><span class = "typ" >Params</span><span class = "pun" >...</span><span class = "pln" > </span><span class = "kwd" >params</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > executeOnExecutor</span><span class = "pun" >(</span><span class = "pln" >sDefaultExecutor</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" >params</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >AsyncTask</span><span class = "pun" ><</span><span class = "typ" >Params</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Progress</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Result</span><span class = "pun" >></span><span class = "pln" > executeOnExecutor</span><span class = "pun" >(</span><span class = "pln" > </span><span class = "typ" >Executor</span><span class = "pln" > </span><span class = "kwd" >exec</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Params</span><span class = "pun" >...</span><span class = "pln" > </span><span class = "kwd" >params</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >mStatus </span><span class = "pun" >!=</span><span class = "pln" > </span><span class = "typ" >Status</span><span class = "pun" >.</span><span class = "pln" >PENDING</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > switch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >mStatus</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > case </span><span class = "pln" > RUNNING</span><span class = "pun" >:</span><span class = "pln" > </span><span class = "kwd" > throw </span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >IllegalStateException</span><span class = "pun" >(</span><span class = "str" > "Cannot execute task:" </span><span class = "pln" > </span><span class = "pun" >+</span><span class = "pln" > </span><span class = "str" > " the task is already running." </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > case </span><span class = "pln" > FINISHED</span><span class = "pun" >:</span><span class = "pln" > </span><span class = "kwd" > throw </span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >IllegalStateException</span><span class = "pun" >(</span><span class = "str" > "Cannot execute task:" </span><span class = "pln" > </span><span class = "pun" >+</span><span class = "pln" > </span><span class = "str" > " the task has already been executed " </span><span class = "pln" > </span><span class = "pun" >+</span><span class = "pln" > </span><span class = "str" > "(a task can be executed only once)" </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > mStatus </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Status</span><span class = "pun" >.</span><span class = "pln" >RUNNING</span><span class = "pun" >;</span><span class = "pln" > onPreExecute</span><span class = "pun" >();</span><span class = "pln" > mWorker</span><span class = "pun" >.</span><span class = "pln" >mParams </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" >params</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" >exec</span><span class = "pun" >.</span><span class = "pln" >execute</span><span class = "pun" >(</span><span class = "pln" >mFuture</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > </span><span class = "kwd" > this </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span> |
AsyncTask是通过execute或executeOnExecutor启动的,通过上边对Executor的介绍可以知道,在executeOnExecutor()中的exec.execute(mFuture)这一行就是根据exec的实现方式来启动mFuture了,问题的关键是exec是如何实现execute()的。在execute中可以看到AsyncTask提供了一个默认的sDefaultExecutor,这个sDefaultExecutor是什么呢:
<span class = "kwd" > private </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > volatile </span><span class = "pln" > </span><span class = "typ" >Executor</span><span class = "pln" > sDefaultExecutor </span><span class = "pun" >=</span><span class = "pln" > SERIAL_EXECUTOR</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >Executor</span><span class = "pln" > SERIAL_EXECUTOR </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >SerialExecutor</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >SerialExecutor</span><span class = "pln" > </span><span class = "kwd" > implements </span><span class = "pln" > </span><span class = "typ" >Executor</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >ArrayDeque</span><span class = "pun" ><</span><span class = "typ" >Runnable</span><span class = "pun" >></span><span class = "pln" > mTasks </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >ArrayDeque</span><span class = "pun" ><</span><span class = "typ" >Runnable</span><span class = "pun" >>();</span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pln" > mActive</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > synchronized </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > execute</span><span class = "pun" >(</span><span class = "kwd" > final </span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pln" > r</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > mTasks</span><span class = "pun" >.</span><span class = "pln" >offer</span><span class = "pun" >(</span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > run</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > try </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > r</span><span class = "pun" >.</span><span class = "pln" >run</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > finally </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > scheduleNext</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >});</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >mActive </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > scheduleNext</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > protected </span><span class = "pln" > </span><span class = "kwd" > synchronized </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > scheduleNext</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >((</span><span class = "pln" >mActive </span><span class = "pun" >=</span><span class = "pln" > mTasks</span><span class = "pun" >.</span><span class = "pln" >poll</span><span class = "pun" >())</span><span class = "pln" > </span><span class = "pun" >!=</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > THREAD_POOL_EXECUTOR</span><span class = "pun" >.</span><span class = "pln" >execute</span><span class = "pun" >(</span><span class = "pln" >mActive</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span> |
默认情况下,sDefaultExecutor就是SerialExecutor类,通过源码可以看到,SerialExecutor是一个严格按照用户提交顺序来执行任务的执行者,其中scheduleNext()函数用来启动下一个任务:
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
THREAD_POOL_EXECUTOR就是真正启动任务的Executor:
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
ThreadPoolExecutor是java自己实现的一种Executor,顾名思义,是个提供线程池的Executor。
由上可以知道,当调用AsyncTask的execute()函数时,AsyncTask会按用户提交任务的顺序,在线程池里串行的执行任务(当前任务运行结束,再运行下一个)。
当然用户也可以提供自己的Executor来改变AsyncTask的运行方式。