Android非同步訊息處理機制學習筆記
阿新 • • 發佈:2019-02-01
(一)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為非同步方法,可以執行耗時操作。