5.AsyncTask注意事項

注意事項:

  • 參數(shù):
AsyncTask<Params,Progress,Result>:Void,Integer卫玖,String稳析,Object等,可以使任意類型或封裝的對象燎竖。
AsyncTask定義了三種泛型類型 Params,Progress和Result要销。
    Params 啟動任務(wù)執(zhí)行的輸入?yún)?shù)--execute()中傳入的參數(shù)构回。
    Progress 后臺任務(wù)執(zhí)行的進(jìn)度--publishProgress中傳入的參數(shù),onProgressUpdate中接收的參數(shù)蕉陋。
    Result 后臺執(zhí)行任務(wù)最終返回的結(jié)果--例如:doInBackgroud中返回的boolean判斷執(zhí)行是否成功捐凭。
  • 不能在子線程生成Async實例

ASync中的Handler為靜態(tài)變量,類加載的時候生成凳鬓,如果在子線程中new Async茁肠,那么Handler也會new,此時子線程new Handler之前沒有prepeare會報錯缩举。

  • execute只能在UI線程調(diào)用垦梆?

如果onPreExecute沒有操作UI,其實也是可以的調(diào)用的仅孩。

  • AsyncTask是串行執(zhí)行的托猩,多個任務(wù)執(zhí)行的時候一個一個等待。但是注意辽慕,每次execute操作京腥,將任務(wù)封裝放入隊列,無論是等待還是執(zhí)行溅蛉,在execute的時候公浪,就馬上調(diào)用onPreExecute了他宛。有可能該任務(wù)需要等待,但是該任務(wù)下的onPreExecute方法已經(jīng)執(zhí)行了欠气。
  • AsyncTask默認(rèn)是串行的厅各,也可以并行操作
mAsyncTask = new MyAsyncTask(myCount);
mAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,myCount+"");

"AsyncTask并不適合進(jìn)行特別耗時的后臺任務(wù),對特別耗時的任務(wù)预柒,建議使用線程池队塘。--開發(fā)藝術(shù)探索上所寫,但是還并未理解"
可能是因為:多個任務(wù)時特別耗時的任務(wù)會影響后面的任務(wù)遲遲不能執(zhí)行宜鸯。用線程池并發(fā)的話憔古,就沒這樣的問題了。

  • 一個AsyncTask對象顾翼,只能執(zhí)行一次execute投放,前面分析源碼的時候已經(jīng)驗證過了奈泪,Running或者Finished的時候再執(zhí)行都會報錯适贸。
  • 無論在任何線程,任何地方使用AsyncTask涝桅,因為該類內(nèi)部的sDefaultExecutor是static類型拜姿,都將只有一個線程池對象。所以冯遂,AsyncTask的任務(wù)都是在這一個線程池中執(zhí)行蕊肥。
    所以,任何線程蛤肌,任何地方壁却,單次或多次調(diào)用AsyncTask執(zhí)行,都是會放入隊列裸准,串行執(zhí)行的展东。
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;   
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();


AsyncTask 缺陷/坑:

  • AsyncTask有多個版本,多種實現(xiàn)炒俱,不具體分析盐肃。
    總之,在3.0以前权悟,最大支持128個線程的并發(fā)砸王,10個任務(wù)的等待。并發(fā)執(zhí)行峦阁,不用等待谦铃。超過138個任務(wù)同時執(zhí)行,會發(fā)生異常:java.util.concurrent.RejectedExecutionException 榔昔。
    在3.0以后驹闰,無論有多少任務(wù)凿跳,都會在其內(nèi)部單線程一個一個執(zhí)行;

  • 異常問題:

Activity退出時疮方,記得在onDestroy中cancle控嗜,并在AsyncTask做isCancel檢查操作,確定Async代碼是否執(zhí)行骡显。否則疆栏,有坑能退出Activity的時候Async還沒有執(zhí)行完,Async執(zhí)行完要更新UI的時候View已經(jīng)銷毀惫谤。

  • 內(nèi)存泄漏問題:
    1.Java特性壁顶,AsyncTask類在Activity是非靜態(tài)內(nèi)部類的時候,默認(rèn)持有外部類Activity的引用溜歪。
    2.AsyncTask持有Activity中的變量若专,如View。

如何避免:
靜態(tài)內(nèi)部類蝴猪。activity若引用调衰,使用activity變量的時候判斷null。例如前篇自阱,Handler防止內(nèi)存泄漏一樣嚎莉。


取消操作任務(wù)操作時,AsyncTask不能中斷的處理沛豌。

cancel的時候趋箩,并不能中斷已經(jīng)開始的任務(wù),因為不能中斷正在執(zhí)行的Thread(但是測試的可以中斷正在執(zhí)行的Async加派,看下面"不確定"叫确,這里就按大部分人說的不能中斷的情況下)。

    //AsyncTask方法
    public final boolean cancel(boolean mayInterruptIfRunning) {
        //標(biāo)記
        mCancelled.set(true);
        return mFuture.cancel(mayInterruptIfRunning);
    }    
    
    //FutureTask方法
    public boolean cancel(boolean mayInterruptIfRunning) {
        if (!(state == NEW &&
              U.compareAndSwapInt(this, STATE, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    if (t != null)
                    //中斷子線程芍锦。應(yīng)該是不能中斷的竹勉,但是測試是可以中斷的。
                        t.interrupt();
                } finally { // final state
                    U.putOrderedInt(this, STATE, INTERRUPTED);
                }
            }
        } finally {
            //最后調(diào)用onCancle()方法
            finishCompletion();
        }
        return true;
    }

mCancelled.set(true);只是在AsyncTask中一個標(biāo)記醉旦,說明是否執(zhí)行過中斷操作饶米,至于有沒有中斷成功isCancelled()的返回值并不能說明。 t.interrupt();才是執(zhí)行中斷線程的主要代碼车胡,現(xiàn)在并不確定該方法是否能中斷線程(網(wǎng)上說不能中斷檬输,而我測試可以中斷)。

解決辦法:

  • 在AsyncTask執(zhí)行的代碼中匈棘,判斷是否中斷丧慈,isCancelled();
  • 如果后臺任務(wù)有頻繁的while操作,可以添加Thread.sleep(1)。因為interrupt的時候逃默,會使阻塞的線程拋異常鹃愤,捕獲異常后return結(jié)束doInBackgroud方法。

不確定:

  • 中斷任務(wù):

Thread/AsyncTask不能中斷完域。Java線程在執(zhí)行的時候软吐,并不能中斷該線程,同樣AsyncTask也是吟税。但是測試的結(jié)果是凹耙,Thread不能中斷,AsyncTask可以中斷肠仪。
按說肖抱,它們都是把執(zhí)行的代碼封裝到了Runnable,開子線程執(zhí)行异旧。但測試就是Thread中斷了意述,AsyncTask沒有中斷。

//testThread.interrupt();不能中斷
public class TestRunnable implements Runnable {
        private static final String TAG = "TestRunnable";
        private int count = 0;

        @Override
        public void run() {
            while (count < 1000) {
                Log.e(TAG, "run: count=" + count);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                   //interrupt會使阻塞的線程拋該異常吮蛹。也可以利用這個特性荤崇,中斷任務(wù)。拋異常的時候return匹涮。
                   // return;
                }
                count++;
            }
        }
    }
// mAsyncTask.execute(count + ""); 按說也因該不能中斷的天试,但是槐壳,測試的時候就是中斷了啊然低。
        @Override
        protected Boolean doInBackground(String... params) {
            while (currentProgress <= 100) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    //return false;
                }
                currentProgress++;
            }
            return true;
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市务唐,隨后出現(xiàn)的幾起案子雳攘,更是在濱河造成了極大的恐慌,老刑警劉巖枫笛,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吨灭,死亡現(xiàn)場離奇詭異,居然都是意外死亡刑巧,警方通過查閱死者的電腦和手機(jī)喧兄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啊楚,“玉大人吠冤,你說我怎么就攤上這事」Ю恚” “怎么了拯辙?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長颜价。 經(jīng)常有香客問我涯保,道長诉濒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任夕春,我火速辦了婚禮未荒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘及志。我一直安慰自己茄猫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布困肩。 她就那樣靜靜地躺著划纽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锌畸。 梳的紋絲不亂的頭發(fā)上勇劣,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天,我揣著相機(jī)與錄音潭枣,去河邊找鬼比默。 笑死,一個胖子當(dāng)著我的面吹牛盆犁,可吹牛的內(nèi)容都是我干的命咐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼谐岁,長吁一口氣:“原來是場噩夢啊……” “哼醋奠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起伊佃,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤窜司,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后航揉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塞祈,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年帅涂,在試婚紗的時候發(fā)現(xiàn)自己被綠了议薪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡媳友,死狀恐怖斯议,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庆锦,我是刑警寧澤捅位,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響艇搀,放射性物質(zhì)發(fā)生泄漏尿扯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一焰雕、第九天 我趴在偏房一處隱蔽的房頂上張望衷笋。 院中可真熱鬧,春花似錦矩屁、人聲如沸辟宗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泊脐。三九已至,卻和暖如春烁峭,著一層夾襖步出監(jiān)牢的瞬間容客,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工约郁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缩挑,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓鬓梅,卻偏偏與公主長得像供置,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子绽快,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容