AsyncTask是一個(gè)很方便用來(lái)在主線程和工作線程切換任務(wù)的工具,但是如果用的不好會(huì)引入不少奇怪的問(wèn)題
坑1:AsyncTask到底是并行還是串行
在回答這個(gè) 問(wèn)題前,我們先看下官方對(duì)AsyncTask的注釋,對(duì)AsyncTask有一個(gè)基本的了解
AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler} * and does not constitute a generic threading framework. AsyncTasks should ideally be * used for short operations (a few seconds at the most.) If you need to keep threads * running for long periods of time, it is highly recommended you use the various APIs * provided by thejava.util.concurrentpackage such as {@link Executor}, * {@link ThreadPoolExecutor} and {@link FutureTask}
從上面AsyncTask源碼注釋可以看出,AsyncTask只適合做短時(shí)間操作的任務(wù)(頂多幾秒),長(zhǎng)時(shí)間的操作不建議使用,但是why?
首先我們來(lái)看下最基礎(chǔ)的AsyncTask的運(yùn)行模型

對(duì)于一個(gè)AsyncTask任務(wù)執(zhí)行時(shí)3個(gè)關(guān)鍵函數(shù)運(yùn)行的環(huán)境如上圖所示,這個(gè)沒(méi)有太多的疑問(wèn)。
那如果多個(gè)AsyncTask同時(shí)執(zhí)行會(huì)有啥不一樣的么?
先上結(jié)論:
同一進(jìn)程內(nèi),多個(gè)AsyncTask 直接通過(guò)execute方法執(zhí)行時(shí),在android3.0以上是串行的

這就解答了源碼注釋里面的一個(gè)疑問(wèn),為什么AsyncTask只適合做短時(shí)間的操作。
因?yàn)樗谴袌?zhí)行的,如果前面的AsyncTask阻塞了,后面的AsyncTask就全部阻塞了。。。。。(多么痛的領(lǐng)悟)
我們來(lái)一起捋一捋代碼,看看為啥得出這樣的結(jié)論
作為一個(gè)可以提交多個(gè)任務(wù) ,且可以在工作線程和主線程切換的工具類,必須有以下幾個(gè)組成
1.線程池
2.事件隊(duì)列
3.handler
先看線程池
一個(gè)最簡(jiǎn)單的AsyncTask方法寫法應(yīng)該是
new AsyncTask().execute();
我們看下execute方法的源碼如下

里面有個(gè)sDefaultExecutor,一看就是一個(gè)線程池,我們來(lái)看下定義

線程池是一個(gè)靜態(tài)變量,也就是說(shuō)對(duì)于同一個(gè)進(jìn)程來(lái)說(shuō),只會(huì)初始化一次,同一進(jìn)程內(nèi)的AsyncTask都運(yùn)行在此進(jìn)程池中。
真相大白了,從任務(wù)隊(duì)列中一個(gè)個(gè)取出任務(wù),執(zhí)行完了再scheduleNext(),串行的執(zhí)行任務(wù)。所以說(shuō)千萬(wàn)不要在AsyncTask中執(zhí)行長(zhǎng)時(shí)間的任務(wù)