(一)Handler
什麼是Handler
- Android消息機制的上層接口,Handler通過發送和處理Message和Runnable對象來關聯相對應線程的MessageQueeu.
- 可以讓對應的Message和Runable在未來的某個時間點進行相應處理;
- 讓自己想要處理的耗時操作放在子線程,讓更新UI的操作放在主線程。
Handler的使用方法
- post(runnable):實際也是調用sendMessage
- sendMessage(message)
Handler機制原理
原理
- Looper通過loop方法輪詢MessageQueue消息,把消息發送給Handler處理;
- MessageQueue消息隊列,先進先出原則,創建Looper時MessageQueue已被創建並和Looper關聯到一起;
- Message就是消息對象,存儲在消息隊列中;
- Handler發送消息和處理消息。要想發送消息必須有Looper(只能發送到與其相關聯的MessageQueue),並且處理Looper發來的消息。
注意:
- ThreadLocal只限於set/get自己線程的信息,Looper保存在ThreadLocal中可以保證每個線程有自己的Looper。
- Looper是怎麼獲取的,通過ThreadLocal的get方法獲取的;Looper什麼時候創建存儲的,也就是ThreadLocal什麼時候調用了set方法呢?Looper.prepare調用時創建一個Looper對象並set在ThreadLocal中;
- Looper.loop創建一個死循環,不斷去消息隊列讀取消息並進行消息分發;
- 每一個Handler要與主線程的消息隊列關聯上,所以不能在內部類創建Handler(在子線程只要主動調用Looper.prepare和Looper.loop方法也是可以使用的)。
Handler引起的內存泄漏以及解決辦法
- 原因
- 內部類持有外部類的匿名引用,導致外部activity無法釋放
- 解決方案
- 使用靜態內部類的Handler;
- 在onDestroy中釋放Handler;
- Handler內部持有外部類的弱引用。
(二)AsyncTask
什麼是AsyncTask
- Android輕量級的異步類,它本質上就是封裝了線程池和Handler的異步框架,因此可以方便的在線程間進行切換。。
- 只能做耗時比較短的工作。
Async的使用方法
3個參數
- 執行耗時任務的參數;
- 執行過程中主線程得到的數據;
- 執行結束返回的數據。
5個方法
- onPreExecute在主線程調用,耗時操作前做一些初始化工作;
- doInBackground比較重要的,做耗時操作,並將結果返回到onPostExecute方法中;
- onPostExecute異步線程執行完時回調;
- publishProgress()在doInBackground中調用,也就是onProgressUpdate的調用間隔;
- onProgressUpdate異步線程執行時,在主線程提供出進度。
機制原理
- AsyncTask的本質是一個靜態的線程池,AsyncTask派生出的子類可以實現不同的異步任務,這些任務都是提交到靜態的線程池中執行;
- 線程池中的工作線程執行doInBackground(mParams)方法執行異步任務;
- 當任務狀態改變之後,工作線程會向UI線程發送消息,AsyncTask內部的InternalHandler相應這些消息,並調用相關的回調函數。
注意事項
內存泄漏:非靜態的內部類持有Activity的引用
- 靜態內部類;
- 弱引用;
- 在onDestroy()中cancle.
生命週期:activity被銷燬時並不會主動銷燬AsyncTask,需要自己調用cancle方法。
- 結果丟失:屏幕旋轉,內存低被回收等導致AsyncTask持有的界面被重新創建,AsyncTask引用是舊的,導致界面更新失敗。
- 並行or串行:在Android1.6之前串行,任務放在線程池順序執行,在1.6-2.3並行,2.3之後爲了系統穩定改成串行,但是也可以執行並行,需要調用executeOnExecutor即可,不建議使用並行,不穩定。
(三)HandlerThread
HandlerThread是什麼
產生背景
- 頻繁的開啓和銷燬Thread子線程執行任務方便但耗費系統資源。
定義
- 本質就是一個Thread線程類,它繼承了Thread
- 有自己的內部looper對象,可以進行Looper循環
- 通過獲取HandlerThread的Looper對象傳遞給Handler對象,可以在handleMessage方法中執行異步任務;
- 優點是不會有阻塞,減少了對性能的消耗;
- 缺點是需要等待,不能同時進行多任務處理,處理效率較低;
- 與線程池和併發不同,HandlerThread是一個串行隊列,HandlerThread背後只有一個線程。
HandlerThread源碼解析
鴻洋大神的分析
(四)IntentService
IntentService是什麼
簡介
- IntentService是繼承Service並處理異步請求的一個類,在IntentService內有一個工作線程來處理耗時操作,啓動IntentService的方式和啓動傳統的Service一樣,同時,當任務執行完成後,IntentService會自動停止,而不需要我們手動或者調用stopSelf().另外,可以多次啓動IntentService,但只有一個IntentService實例,而每一個耗時操作會以工作隊列的方式在IntentService的onHandleIntent回調方法中執行,並且,每次只會執行一個工作線程,執行完第一個再執行第二個,直到最後一個執行完後自動銷燬。
IntentService是什麼
- 它本質是一種特殊的Service,繼承自Service並且本身就是一個抽象類;
- 它內部通過HandleThread和Handler實現異步操作。
IntentService使用
- 創建IntentService時只需要實現onHandleIntent和構造方法,onHandleIntent爲異步方法,可以執行耗時操作。