android 的多線程 實現方法,android 線程的高級使用( 五 )


(3)onProgressUpdate(Progress... values)
在 UI 線程上工作,會在 doInBackground() 中調用 publishProgress(Progress) 方法后執行,此方法用于在后臺計算仍在執行時(也就是 doInBackgound() 還在執行時)將計算執行進度通過 UI 顯示出來 。例如,可以通過動畫進度條或顯示文本字段中的日志 , 從而方便用戶知道后臺任務執行的進度 。
(4)onPostExecute(Result result)
在 UI 線程上工作,在任務執行完畢(即 doInBackground(Result) 執行完畢)并將執行結果傳過來的時候工作 。
使用規則:
(1)AsyncTask 是個抽象類,所以要創建它的子類實現抽象方法
(1)AsyncTask 類必須是在 UI 線程中被加載,但在Android 4.1(API 16)開始,就能被自動加載完成 。
(2)AsyncTask 類的實例對象必須在 UI 線程中被創建 。
(3)execute() 方法必須是在 UI 線程中被調用 。
(4)不要手動調用方法 onPreExecute()、onPostExecute()、doInBackground()、onProgressUpdate()
(5)任務只能執行一次(如果嘗試第二次執行,將拋出異常) 。即一個AsyncTask對象只能調用一次execute()方法 。
原理:
其源碼中原理還是 Thread 與 Handler 的實現 , 其包含 兩個線程池 , 一個 Handler,如下所示:
名稱類型作用
SERIAL_EXECUTOR線程池分發任務,串行分發,一次只分發一個任務
THREAD_POOL_EXECUTOR線程池執行任務,并行執行,執行的任務由 SERIAL_EXECUTOR 分發
InternalHandlerHandler負責子線程與主線程的溝通,通知主線程做 UI 工作
一方面減少了每個并行任務獨自建立線程的開銷,另一方面可以管理多個并發線程的公共資源,從而提高了多線程的效率 。所以ThreadPoolExecutor比較適合一組任務的執行 。Executors利用工廠模式對ThreadPoolExecutor進行了封裝 。
Executors提供了四種創建ExecutorService的方法,他們的使用場景如下:
1. Executors.newFixedThreadPool()
創建一個定長的線程池,每提交一個任務就創建一個線程,直到達到池的最大長度,這時線程池會保持長度不再變化 。
當線程處于空閑狀態時,它們并不會被回收,除非線程池被關閉 。當所有的線程都處于活動狀態時,新任務都會處于等待狀態,直到有線程空閑出來 。
只有核心線程并且不會被回收,能夠更加快速的響應外界的請求 。
2. Executors.newCachedThreadPool()
創建一個可緩存的線程池,如果當前線程池的長度超過了處理的需要時,它可以靈活的回收空閑的線程,當需要增加時,它可以靈活的添加新的線程,而不會對池的長度作任何限制
線程數量不定的線程池,只有非核心線程,最大線程數為 Integer.MAX_VALUE 。當線程池中的線程都處于活動狀態時,線程池會創建新的線程來處理新任務,否則利用空閑的線程來處理新任務 。線程池中的空閑線程具有超時機制,為 60s 。
任務隊列相當于一個空集合,導致任何任務都會立即被執行,適合執行大量耗時較少的任務 。當整個線程池都處于限制狀態時,線程池中的線程都會超時而被停止 。
3. Executors.newScheduledThreadPool()
創建一個定長的線程池 , 而且支持定時的以及周期性的任務執行,類似于Timer 。
非核心線程數沒有限制,并且非核心線程閑置的時候立即回收,主要用于執行定時任務和具有固定周期的重復任務 。
4. Executors.newSingleThreadExecutor()
創建一個單線程化的executor,它只創建唯一的worker線程來執行任務
只有一個核心線程,保證所有的任務都在一個線程中順序執行,意義在于不需要處理線程同步的問題 。