深入理解Android非同步訊息處理機制
一、概述
Android 中的非同步訊息處理主要分為四個部分組成,Message、Hndler、MessageQueue 和 Looper。其關係如下圖所示:
1. Message 是執行緒之間傳遞的訊息,它可以在內部攜帶少量資訊,用於在不同執行緒之間交換資料。
2. MessageQueue 是訊息佇列,它主要用於存放所有由 Handler 傳送過來的訊息,這部分訊息會一直在訊息佇列中,等待被處理。每個執行緒中只會有一個 MessageQueue 物件。
3. Handler 是處理者,它主要用於傳送和處理訊息。 傳送訊息一般使用 handler 的 sendMessage()方法,處理訊息會呼叫 handleMessage() 方法。
4. Looper 是每個執行緒中 MessageQueue 的管家, 呼叫 loop() 方法後,就會進入到一個無限迴圈當中,然後每當發現 MessageQueue 中存在一條訊息,就會將其取出,並傳遞到 handleMessage()方法當中。每個執行緒中也只會有一個Looper物件。
二、詳細介紹
1、Looper
對於Looper主要是prepare()和loop()兩個方法。
public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(true)); }
sThreadLocal是一個ThreadLocal物件,可以在一個執行緒中儲存變數。Looper 就是儲存在sThreadLocal裡面。這個方法被呼叫後,首先會判斷當前執行緒裡面有沒有 Looper物件,如果沒有就會建立一個 Looper 物件,如果存在則會丟擲異常。可見,prepare()方法,不能被呼叫兩次。這就保證了一個執行緒只有一個Looper物件。
接下來我們看一下Looper的建構函式:
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mRun = true; mThread = Thread.currentThread(); }
在 Looper 的建構函式中,建立了 MessageQueue 物件,這也保證了一個執行緒只有一個 MessageQueue 物件。
然後我們看看 loop() 方法:
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycle(); } }
這個方法先呼叫 myLooper() 方法,得到 sThreadLocal 中儲存的 Looper 物件,並得到 looper 物件對應的 MessageQueue 物件,然後就進入無限迴圈。
該迴圈主要包括:取出一條訊息,如果沒有訊息則阻塞; 呼叫 msg.target.dispatchMessage(msg);把訊息交給msg的target的dispatchMessage方法去處理。
Looper主要作用:
1、 與當前執行緒繫結,保證一個執行緒只會有一個Looper例項,同時一個Looper例項也只有一個MessageQueue。
2、 loop()方法,不斷從MessageQueue中去取訊息,交給訊息的target屬性的dispatchMessage去處理。
2、Handler
在使用Handler之前,我們都是初始化一個例項,比如用於更新UI執行緒,我們會在宣告的時候直接初始化,或者在onCreate中初始化Handler例項。
private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case value: break; default: break; } }; };
三、小結
1、首先Looper.prepare()在本執行緒中儲存一個Looper例項,然後該例項中儲存一個MessageQueue物件;因為Looper.prepare()在一個執行緒中只能呼叫一次,所以MessageQueue在一個執行緒中只會存在一個。大家可能還會問,那麼在Activity中,我們並沒有顯示的呼叫Looper.prepare()和Looper.loop()方法,為啥Handler可以成功建立呢,這是因為在Activity的啟動程式碼中,已經在當前UI執行緒呼叫了Looper.prepare()和Looper.loop()方法
2、Looper.loop()會讓當前執行緒進入一個無限迴圈,不端從MessageQueue的例項中讀取訊息,然後回撥msg.target.dispatchMessage(msg)方法。
3、Handler的構造方法,會首先得到當前執行緒中儲存的Looper例項,並與Looper例項中的MessageQueue相關聯。
4、Handler的sendMessage方法,會給msg的target賦值為handler自身,然後加入MessageQueue中。
5、在構造Handler例項時,我們會重寫handleMessage方法,也就是msg.target.dispatchMessage(msg)最終呼叫的方法。
相關文章
- Android中的非同步訊息處理機制Android非同步
- 深入理解Android訊息機制Android
- 理解 Android 訊息機制Android
- 原始碼分析:Android訊息處理機制原始碼Android
- Android應用程式訊息處理機制Android
- Android非同步訊息機制Android非同步
- 深入理解windows 訊息機制Windows
- Android原始碼解析之一 非同步訊息機制Android原始碼非同步
- Android 深入理解 Notification 機制Android
- Android訊息機制HandlerAndroid
- android訊息機制—HandlerAndroid
- Android 之訊息機制Android
- 深入理解非同步事件機制非同步事件
- Cloud Foundry架構和訊息處理機制Cloud架構
- Handler訊息處理機制原始碼解析 上原始碼
- android 訊息傳遞機制進階EventBus的深入探究Android
- 回轉壽司你一定吃過!——Android訊息機制(處理)Android
- Android訊息機制Handler用法Android
- 深入 Go 的錯誤處理機制,理解設計思想Go
- Android 訊息機制詳解(Android P)Android
- 深入理解 OpenMP 執行緒同步機制執行緒
- 深入理解Apache Hudi非同步索引機制Apache非同步索引
- Android的Handler訊息機制 解析Android
- Android Handler 訊息機制詳述Android
- 深入淺出 Runtime(三):訊息機制
- Android 訊息機制:Handler、MessageQueue 和 LooperAndroidOOP
- 全面剖析Android訊息機制原始碼Android原始碼
- Android Handler MessageQueue Looper 訊息機制原理AndroidOOP
- 基於TimeLine模型的訊息同步機制模型
- 由外到內——剖析Android訊息機制Android
- 06.Android之訊息機制問題Android
- Android進階;Handler訊息機制詳解Android
- Android Handler訊息機制原始碼解讀Android原始碼
- Android-Handler訊息機制實現原理Android
- 深入剖析setState同步非同步機制非同步
- 詳解 Handler 訊息處理機制(附自整理超全 Q&A)
- Android訊息機制全面解析(Handler,MessageQueue,Looper,Threadlocal)AndroidOOPthread
- Android之Handler訊息傳遞機制詳解Android