深入理解AsyncTask

2022-08-31 16:00:21 字數 2351 閱讀 9994

眾所周知,在android中如果要執行耗時的操作,一般是在子執行緒中處理,使用new thread的方法實現是最常見的方法之一。今天,我們要講的是另外乙個,android提供的非同步任務類asynctask,底層是使用執行緒池實現的。

一、android的執行緒

執行緒是作業系統的最小執行單位,它的建立和銷毀都會消耗一定的系統資源,如果頻繁的建立和銷毀,顯然不是高效的做法,正確的做法是,採用執行緒池,快取一定量的執行緒,通過復用這些執行緒,避免造成極大的系統開銷。

二、asynctask

該類的宣告如下:

public abstract class asynctask

其中各個引數的含義如下:

params:開始非同步任務執行時傳入的引數型別;

result:非同步任務執行完成後,返回的結果型別;

如果asynctask確定不需要傳遞具體引數,那麼這三個泛型引數可以用void來代替。

三、asynctask原始碼

asynctask內部封裝了2個執行緒池:serialexecutor和thread_pool_executor,和1個handler(intenthandler)。其中serialexecutor執行緒池用於任務的排隊,讓需要執行的多個耗時任務,按順序排列,thread_pool_executor執行緒池才真正地執行任務,internalhandler用於從工作執行緒切換到主線程。部分原始碼如下:

private static class serialexecutor implements executor  finally 

}});

if (mactive == null)

}protected synchronized void schedulenext()

}}

threadpoolexecutor threadpoolexecutor = new threadpoolexecutor(

core_pool_size, maximum_pool_size, keep_alive_seconds, timeunit.seconds,

spoolworkqueue, sthreadfactory);

threadpoolexecutor.allowcorethreadtimeout(true);

thread_pool_executor = threadpoolexecutor;

private static class internalhandler extends handler 

@suppresswarnings()

@override

public void handlemessage(message msg)

}}

四、注意事項

1、因為執行後的結果要傳遞到主線程,所以使用handler進行工作執行緒和主線程的切換,所以asynctask建立例項和execute需要在主線程呼叫;

2、onpreexecute(),onprogressupdate(progress... values),onpostexecute(result result),oncancelled()方法是在主線程執行的,而doinbackground(params... params)是在工作執行緒執行;

3、執行順序:onpreexecute() --> doinbackground() --> publishprogress() --> onprogressupdate() --> onpostexecute(),如果不需要執行更新進度則為onpreexecute() --> doinbackground() --> onpostexecute(),其中publishprogress方法在doinbackground方法中呼叫,會觸發onprogressupdate方法;

5、乙個任務例項只能執行一次,如果執行第二次將會丟擲異常。

五、asynctask使用不當的後果

1、生命週期:asynctask不與任何元件繫結生命週期,所以在activity或者fragment中建立執行asynctask時,最好在activity或fragment的ondestory()呼叫 cancel(boolean);

2、記憶體洩漏:如果asynctask被宣告為activity的非靜態的內部類,那麼asynctask會保留乙個對建立了asynctask的activity的引用。如果activity已經被銷毀,asynctask的後台執行緒還在執行,它將繼續在記憶體裡保留這個引用,導致activity無法被**,引起記憶體洩露;

3、 結果丟失:螢幕旋轉或activity在後台被系統殺掉等情況會導致activity的重新建立,之前執行的asynctask(非靜態的內部類)會持有乙個之前activity的引用,這個引用已經無效,這時呼叫onpostexecute()再去更新介面將不再生效。

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

mysql 索引深入理解 深入理解MySql的索引

為什麼索引能提高查詢速度 先從 mysql的基本儲存結構說起 mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶每個資料頁中的記錄又可以組成乙個單向鍊錶 每個資料頁都會為儲存在它裡邊兒的記錄生成乙個頁目錄,在通過主鍵查詢某條記錄的時候可以在頁目錄中使用二分法快速定位到對應...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...