[转载]Android的AsyncTask源码分析 - 周柯文 - 博客园

[转载]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的运行方式。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

登录

注册