Android消息機制Handler用法總結
1.簡述
Handler消息機制主要包括: MessageQueue、 Handler、 Looper、Message。
- Message:需要傳遞的消息,可以傳遞數(shù)據(jù);
- MessageQueue:消息隊列,但是它的內(nèi)部實現(xiàn)并不是用的隊列,而是通過單鏈表的數(shù)據(jù)結構來維護消息列表,因為單鏈表在插入和刪除上比較有優(yōu)勢。主要功能是向消息池投遞消息( MessageQueue.enqueueMessage)和取走消息池的消息( MessageQueue.next)。?
- Handler:消息輔助類,主要功能是向消息池發(fā)送各種消息事件( Handler.sendMessage)和處理相應消息事件( Handler.handleMessage);?
- Looper:消息控制器,不斷循環(huán)執(zhí)行( Looper.loop),從MessageQueue中讀取消息,按分發(fā)機制將消息分發(fā)給目標處理者。
2.異步線程切換原理
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
每一個異步線程,都維護著唯一的一個Looper,每一個Looper會初始化(維護)一個MessageQueue,之后進入一個無限循環(huán)一直在讀取MessageQueue中存儲的消息,如果沒有消息那就一直阻塞等待。
我們在實例化handler的過程中,會先得到當前所在線程的looper對象,之后得到與該looper對象相對應的消息隊列,看源碼Handler中持有Looper、MessageQueue。
private static void handleCallback(Message message) { message.callback.run(); } final Looper mLooper; final MessageQueue mQueue; final Callback mCallback;
當我們發(fā)送消息的時候,即handler.sendMessage或者handler.post,會將msg中的target賦值為handler自身,這就是實現(xiàn)message從一個線程到另外一個線程的傳遞的本質(zhì),之后加入到消息隊列中。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
我們一般會重寫handlerMessage方法處理消息,這將會在msg.target.disPatchMessage方法中被回調(diào),從而實現(xiàn)了message從一個線程到另外一個線程的傳遞。
3.總結
- 1.Handler 的背后有 Looper、MessageQueue 支撐,Looper 負責消息分發(fā),MessageQueue 負責消息管理;
- 2.在創(chuàng)建 Handler 之前一定需要先創(chuàng)建 Looper,Looper 有退出的功能,但是主線程的 Looper 不允許退出;
- 3.異步線程Looper,Looper.prepare()創(chuàng)建Looper,Looper.loop()開始輪詢,需要自己調(diào)用 Looper.myLooper().quit()退出;
- 4.Runnable 被封裝進了 Message,可以說是一個特殊的 Message;
- 5.Handler.handleMessage() 所在的線程是 Looper.loop() 方法被調(diào)用的線程;
- 6.Handler內(nèi)存泄漏的原因
原因:MessageQueue持有Message,Message持有activity,delay多久,message就會持有activity多久。
解決方案:靜態(tài)內(nèi)部類、弱引用,最后不要忘記調(diào)用Handler.removeCallbacksAndMessages(null)清空所有消息。
public class SampleActivity extends Activity { /** * Instances of static inner classes do not hold an implicit * reference to their outer class. */ private static class MyHandler extends Handler { private final WeakReference<SampleActivity> mActivity; public MyHandler(SampleActivity activity) { mActivity = new WeakReference<SampleActivity>(activity); } @Override public void handleMessage(Message msg) { SampleActivity activity = mActivity.get(); if (activity != null) { // ... } } } // MyHandler private final MyHandler mHandler = new MyHandler(this); /** * Instances of anonymous classes do not hold an implicit * reference to their outer class when they are "static". */ private static final Runnable sRunnable = new Runnable() { @Override public void run() { /* ... */ } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Post a message and delay its execution for 10 minutes. mHandler.postDelayed(sRunnable, 1000 * 60 * 10); // Go back to the previous Activity. finish(); } @Override protected void onDestroy() { super.onDestroy(); //mHandler.removeCallbacksAndMessages(null); } }
以上所述是小編給大家介紹的Android消息機制Handler用法總結,希望對大家有所幫助。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
深入android中The connection to adb is down的問題以及解決方法
本篇文章是對android中The connection to adb is down的問題以及解決方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05RxJava+Retrofit實現(xiàn)網(wǎng)絡請求封裝的方法
Retrofit是當前應用非常廣泛的網(wǎng)絡請求框架,通常結合RxJava來進行網(wǎng)絡請求,本文將展示一個采用RxJava+Retrofit的網(wǎng)絡請求demo,感興趣的可以了解一下2019-04-04android dialog根據(jù)彈窗等級排序顯示的示例代碼
這篇文章主要介紹了android dialog根據(jù)彈窗等級排序顯示,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Android RecyclerView上拉加載更多功能回彈實現(xiàn)代碼
這篇文章主要介紹了Android RecyclerView上拉加載更多功能回彈實現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02Android自定義textview實現(xiàn)豎直滾動跑馬燈效果
這篇文章主要為大家詳細介紹了Android自定義textview實現(xiàn)豎直滾動跑馬燈效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06基于GridView和ActivityGroup實現(xiàn)的TAB分頁(附源碼)
今天為大家介紹下使用GridView和ActivityGroup實現(xiàn)的分頁,這里需要將Activity轉(zhuǎn)換成Window,然后再換成成View添加到容器中,具體實現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06Android自定義View實現(xiàn)仿網(wǎng)易音樂唱片播放效果
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)仿網(wǎng)易音樂唱片播放效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04Android框架Volley之利用Imageloader和NetWorkImageView加載圖片的方法
這篇文章主要介紹了Android框架Volley之利用Imageloader和NetWorkImageView加載圖片的實現(xiàn)方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-05-05