Android Handler深入學(xué)習(xí)(源碼分析)

目錄:

目錄

1. 背景

在上一篇關(guān)于 Android Handler 使用方法 的文章中學(xué)會(huì)了 Handler 的使用方法,然而又是知其然不知其所以然的狀態(tài),這次較深入的學(xué)習(xí)一下 Handler 的源碼。

在分析源碼之前,先來了解一下Message、MessageQueue、Looper這幾個(gè)對(duì)象。

1.1 Message 消息

定義:是線程間通訊的數(shù)據(jù)單元,包含著描述信息及任意數(shù)據(jù)對(duì)象,發(fā)送到 Handler。

在實(shí)際使用中,我們?cè)诠ぷ骶€程中通過 Handler.sendMessage(Message),將攜帶數(shù)據(jù)的 Message 信息發(fā)送給 Handler,然后再由 Handler 處理,根據(jù)不同的信息,通知主線程作出相對(duì)應(yīng)的 UI 工作。

官方文檔說明:

/**
 * 定義包含著描述信息及任意數(shù)據(jù)對(duì)象的可發(fā)送到 Handler 的信息。額外包含可以不被分配的兩個(gè) int 字段及一個(gè) Object 字段。
 * 獲取 Message 對(duì)象最好的方法是調(diào)用 Message.obtain() 或 調(diào)用 Handler.obtainMessage() 方法來獲取,調(diào)用該方法將從可回收的對(duì)象池中獲取對(duì)象。
 */
public final class Message implements Parcelable {
    /**
     * 用戶定義的消息代碼,以便接收者能夠識(shí)別此消息。每個(gè) Handler 都有自己的消息代碼命名空間,因此不必?fù)?dān)心你的 Handler 與其他 Handler 起沖突。
     */
    public int what;

    /**
     * 如果只需要存儲(chǔ)幾個(gè)整數(shù)值,以 arg1 和 arg2 為變量去使用 setData(Bundle) 是較低成本的替代選擇方法。
     */
    public int arg1;
    public int arg2;

    /**
     * 發(fā)送給接收者的任意對(duì)象,當(dāng)使用 Messager 跨進(jìn)程發(fā)送消息時(shí),如果包含著可序列化的框架類時(shí),Message必須是非空的。使用setData()來傳輸數(shù)據(jù)。
     * 注意,Android 2.2發(fā)行版之前不支持此處的Parcelable對(duì)象。
     */
    public Object obj;
    ···略···

1.2 MessageQueue 消息隊(duì)列

定義:用來存儲(chǔ) Message 的數(shù)據(jù)隊(duì)列。

官方文檔說明:

/**
 * 包含著一系列由 Looper 分發(fā)的 Message 的一個(gè)低級(jí)類。
 * Message 不是直接添加到 MessageQueue 中的,而是通過與 Looper 關(guān)聯(lián)的 Handler 對(duì)象來添加的。
 * 你可以使用“l(fā)oop.myQueue()”方法來獲取當(dāng)前線程的 MessageQueue 對(duì)象。
 */
public final class MessageQueue {
    private static final String TAG = "MessageQueue";
    ···略···
}

1.3 Looper 消息循環(huán)器

定義:用于為線程執(zhí)行消息循環(huán)的一個(gè)類。是 MessageQueue 與 Handler 之間的通訊媒介。

官方文檔說明:

/**
  * 用于為線程執(zhí)行消息循環(huán)的一個(gè)類。
  * 線程默認(rèn)情況下沒有與之關(guān)聯(lián)的消息循環(huán);要?jiǎng)?chuàng)建一個(gè),在將要運(yùn)行循環(huán)的線程中調(diào)用 Looper.prepare(),然后調(diào)用 Looper.loop() 讓它處理消息,直到循環(huán)停止。
  * 與消息循環(huán)的大多數(shù)交互都是通過 Handler 類進(jìn)行的。
  * 這是一個(gè)典型的 Looper 線程實(shí)現(xiàn)的例子,使用 Looper.prepare() 和 Looper.loop() 方法創(chuàng)建一個(gè) Handler 對(duì)象與 Looper 進(jìn)行通信。
  * <pre>
  *  class LooperThread extends Thread {
  *      public Handler mHandler;
  *
  *      public void run() {
  *          Looper.prepare();
  *
  *          mHandler = new Handler() {
  *              public void handleMessage(Message msg) {
  *                  // 在這里處理傳入的消息
  *              }
  *          };
  *
  *          Looper.loop();
  *      }
  *  }</pre>
  */
public final class Looper {
     /*
     * API 實(shí)現(xiàn)注意事項(xiàng):
     *
     * 該類包含設(shè)置和管理基于 MessageQueue 的事件循環(huán)所需的代碼。
     * 影響隊(duì)列狀態(tài)的api應(yīng)該在 MessageQueue 或 Handler 上定義,而不是在 Looper 本身上定義。
     * 例如,在隊(duì)列上定義空閑處理程序和同步屏障,而在 Looper 上定義線程準(zhǔn)備、循環(huán)和退出。
     */

    private static final String TAG = "Looper";
    ···略···
}

1.4 Message、MessageQueue、Looper之間的關(guān)系

一句話概括:
存儲(chǔ)在 MessageQueue 中的 MessageLooper 循環(huán)分發(fā)到指定的 Handler 中進(jìn)行處理。

2. Handler 通信機(jī)制原理

關(guān)于Handler的通信機(jī)制工作原理,請(qǐng)看 Carson_Ho大佬的 Android Handler:圖文解析 Handler通信機(jī)制 的工作原理 寫的超棒,圖文解析,一目了然。引用其中一Handler通信流程示意圖,如下:

在這里插入圖片描述

Thread、Handler、Looper三者之間的數(shù)量對(duì)應(yīng)關(guān)系;

  • 一個(gè) Thread 可以有多個(gè) Handler。
  • 一個(gè) Handler 只能關(guān)聯(lián)一個(gè) Looper 對(duì)象。
  • 反之,一個(gè) Looper 可以被多個(gè) Handler 所關(guān)聯(lián)。

3. 源碼分析

根據(jù)上一篇博客中介紹的Android Handler 使用方法, 我們針對(duì) Handler.sendMessage(msg) 方法展開分析,分為3步:

  1. 創(chuàng)建 Handler 對(duì)象
  2. 創(chuàng)建 Message 對(duì)象
  3. 分發(fā) Message

3.1 創(chuàng)建 Handler 對(duì)象

創(chuàng)建一個(gè) Handler 對(duì)象,也就是實(shí)例化一個(gè) Handler 對(duì)象,在實(shí)際的使用中,我也發(fā)現(xiàn)有存在三種情況,分別是:

  1. 在主線程上新建一個(gè) Handler 對(duì)象,提供應(yīng)用程序的 主Looper 對(duì)象與之綁定關(guān)聯(lián)。
  2. 創(chuàng)建一個(gè)繼承于 Handler類的靜態(tài)內(nèi)部類,防止內(nèi)存泄漏。
  3. 在子線程上創(chuàng)建 Handler 對(duì)象。

我將一一展開分析:

3.1.1 在主線程上新建一個(gè) Handler 對(duì)象,提供應(yīng)用程序的 主Looper 對(duì)象與之綁定關(guān)聯(lián)

如下,我們?cè)谥骶€程中新建 Handler 對(duì)象,

//在主線程中新建 Handler 對(duì)象,并提供應(yīng)用程序的 主Looper
mHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //消息處理

    }
};

通過上述代碼,我們創(chuàng)建了一個(gè) Handler 對(duì)象,并關(guān)聯(lián)應(yīng)用程序的 主Looper 對(duì)象。
這個(gè)時(shí)候我們看一下 Handler類 的構(gòu)造函數(shù),如下所示:

/**
 * Use the provided {@link Looper} instead of the default one.
 * 使用提供的 Looper對(duì)象, 而不是使用默認(rèn)的Looper對(duì)象
 * @param Looper 不能為 null
 */
public Handler(@NonNull Looper looper) {
    this(looper, null, false);
}

可以發(fā)現(xiàn),我們提供給 Handler 的 Looper 是通過 Looper.getMainLooper() 獲取的。往下看:

/**
 * 返回應(yīng)用程序的 主Looper, 它存在于應(yīng)用程序的主線程中。
 */
public static Looper getMainLooper() {
    synchronized (Looper.class) {
        //返回sMainLooper, 下一步看看sMainLooper是怎么創(chuàng)建 Looper 對(duì)象的。
        return sMainLooper; 
    }
}

如上所訴,getMainLooper() 返回 全局變量 sMainLooper 對(duì)象,所以我們需要看 sMainLooper 是什么時(shí)候被賦值的,如下所示,在 prepareMainLooper() 方法中,sMainLooper 被 myLooper 賦值:
/**
 * 將當(dāng)前線程初始化為 Looper,并將其標(biāo)記為應(yīng)用程序的 主Looper
 * 應(yīng)用程序的 主Looper 是由 Android環(huán)境 創(chuàng)建的,所以永遠(yuǎn)不需要自己調(diào)用這個(gè)函數(shù)
 */
public static void prepareMainLooper() {
    //調(diào)用 prepare() 方法,如果當(dāng)前線程沒有 Looper 對(duì)象,就為之新創(chuàng)建一個(gè) Looper 對(duì)象。
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        //返回當(dāng)前線程所關(guān)聯(lián)的 Looper 對(duì)象。
        sMainLooper = myLooper();
    }
}

上一步 prepareMainLooper 中:調(diào)用了 prepare(false) 來創(chuàng)建 Looper 對(duì)象,具體如下:
private static void prepare(boolean quitAllowed) {
    //sThreadLocal.get() 返回 Looper || null,如果返回 Looper 對(duì)象,即代表已經(jīng)為該線程創(chuàng)建了 Looper 對(duì)象,
    //從而拋出異常,提示:“每個(gè)線程只能創(chuàng)建一個(gè)Looper”
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    //否則,調(diào)用 new Looper()方法新建一個(gè) Looper 對(duì)象,并放入 sThreadLocal 變量中。
    sThreadLocal.set(new Looper(quitAllowed)); //quitAllowed = false
}

上一步 prepare() 中:調(diào)用了 new Looper() 方法來新創(chuàng)建 Looper 對(duì)象,具體如下:
private Looper(boolean quitAllowed) {
    //新建一個(gè) MessageQueue 
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}


在 prepareMainLooper() 方法中,如果 sMainLooper 為 null,就賦值 sMainLooper = myLooper(); , myLooper() 方法如下:
/**
 * 返回當(dāng)前線程所關(guān)聯(lián)的 Looper 對(duì)象,如果所調(diào)用的線程沒有關(guān)聯(lián)的 Looper 對(duì)象,就返回 null
 */
public static @Nullable Looper myLooper() {
    //獲取的 Looper 對(duì)象,是在 prepare() 方法中通過 sThreadLocal.set(new Looper(quitAllowed)); 所創(chuàng)建的
    return sThreadLocal.get();
}

上述代碼中,getMainLooper() 方法中的 sMainLooper 是通過 prepareMainLooper() 進(jìn)行賦值的,具體代碼分析如上所述,其流程圖如下所示:


在這里插入圖片描述

3.1.2 創(chuàng)建一個(gè)繼承于 Handler類的靜態(tài)內(nèi)部類,防止內(nèi)存泄漏

上述創(chuàng)建 Handler 對(duì)象的方法是 new Handler(Looper.getMainLooper()) ,通過 Looper.getMainLooper() 方法獲取 Looper 對(duì)象,然后傳入到 Handler 的構(gòu)造函數(shù)中,構(gòu)成綁定關(guān)聯(lián)關(guān)系。
但在實(shí)際開發(fā)中,我們通常將 Handler 寫成靜態(tài)內(nèi)部類的形式,如下:

//創(chuàng)建 Handler 對(duì)象
mHandler = new MyHandler(this);

/**
 * 將 Handler 寫成靜態(tài)內(nèi)部類,防止內(nèi)存泄露
 */
public static class MyHandler extends Handler {
    WeakReference<HandlerAddThreadActivity> weakReference;

    public MyHandler(HandlerAddThreadActivity activity) {
        weakReference = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //處理收到的信息
    }
}

思考: 疑問?根據(jù)上面的代碼,我們沒有傳遞 Looper 對(duì)象給 Handler 去綁定關(guān)聯(lián), 那 Handler 為何又能正常工作?
帶著疑惑上路:

首先看一下 Handler類 的默認(rèn)構(gòu)造函數(shù)

/**
 * 默認(rèn)構(gòu)造函數(shù)將這個(gè)處理程序與當(dāng)前線程的{@link Looper}關(guān)聯(lián)起來。
 * 如果此線程沒有l(wèi)ooper,則此處理程序?qū)o法接收消息,因此將引發(fā)異常。
 */
public Handler() {
    this(null, false);
}

public Handler(@Nullable Callback callback, boolean async) {
    ···略···
    //返回與當(dāng)前線程關(guān)聯(lián)的Looper對(duì)象。如果調(diào)用線程沒有關(guān)聯(lián)的 Looper 對(duì)象,則返回null
    mLooper = Looper.myLooper();
    //如果 mLooper 為null,則拋出異常。
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread " + Thread.currentThread()
                    + " that has not called Looper.prepare()");
    }
    //獲取該 Looper 的 MessageQueue
    mQueue = mLooper.mQueue;

    //callback = null && async = false
    mCallback = callback;
    mAsynchronous = async;
}

看著不明顯,mLooper 是通過 Looper.myLooper() 方法獲得的.
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

但這個(gè)時(shí)候我想起了 prepareMainLooper() 方法。
/**
 * 將當(dāng)前線程初始化為 Looper,并將其標(biāo)記為應(yīng)用程序的 主Looper
 * 應(yīng)用程序的 主Looper 是由 Android環(huán)境 創(chuàng)建的,所以永遠(yuǎn)不需要自己調(diào)用這個(gè)函數(shù)
 */
public static void prepareMainLooper() {
    //調(diào)用 prepare() 方法,如果當(dāng)前線程沒有 Looper 對(duì)象,就為之新創(chuàng)建一個(gè) Looper 對(duì)象。
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        //返回當(dāng)前線程所關(guān)聯(lián)的 Looper 對(duì)象。
        sMainLooper = myLooper();
    }
}

疑問解除,無論我們有沒有手動(dòng)添加 Looper 給 Handler, Android環(huán)境都會(huì)為我們自動(dòng)創(chuàng)建一個(gè)主線程的主Looper對(duì)象。

總結(jié): 我們創(chuàng)建的 MyHandler 靜態(tài)內(nèi)部類,其實(shí)也是在主線程上創(chuàng)建的, Android環(huán)境會(huì)為我們自動(dòng)創(chuàng)建一個(gè)應(yīng)用程序的 主Looper 對(duì)象,主線程與 主Looper 綁定關(guān)聯(lián)。

3.1.3 在子線程上創(chuàng)建 Handler 對(duì)象

ok, 解除了剛剛的疑問,我又問自己,那在子線程創(chuàng)建 Handler 對(duì)象呢?
當(dāng)然,如果你在子線程中新創(chuàng)建一個(gè) Handler 對(duì)象,創(chuàng)建的方法為:

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        //為當(dāng)前線程創(chuàng)建一個(gè) Looper 
        Looper.prepare();
        
        //在子線程中創(chuàng)建 Handler 對(duì)象
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // 在這里處理傳入的消息
            }
        };
        //開始消息循環(huán)
        Looper.loop();
    }
}

在子線程上,我們通過調(diào)用 prepare() 來為當(dāng)前線程創(chuàng)建一個(gè) Looper 對(duì)象

/** 將當(dāng)前線程初始化為 Looper 對(duì)象,在實(shí)際開始循環(huán)之前創(chuàng)建并引用該 Looper 對(duì)象。
 * 請(qǐng)確保在調(diào)用此方法后調(diào)用 loop() 方法,并通過調(diào)用 quit() 結(jié)束它
 */
public static void prepare() {
    prepare(true);
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

并且在 Handler 與 Looper 構(gòu)成綁定關(guān)聯(lián)關(guān)系后,通過調(diào)用 Looper.loop() 方法開始消息循環(huán)。

3.2 創(chuàng)建 Message消息對(duì)象

關(guān)于創(chuàng)建 Message 對(duì)象有兩種創(chuàng)建方法,分別是:

  1. Message myMessage = new Message();
  2. Message myMessage = Message.obtain()
/**
 * 從全局池返回一個(gè)新的消息實(shí)例。允許我們?cè)谠S多情況下避免分配新對(duì)象。
 */
public static Message obtain() {
    synchronized (sPoolSync) {
        if (sPool != null) {
            Message m = sPool;
            sPool = m.next;
            m.next = null;
            m.flags = 0; // clear in-use flag
            sPoolSize--;
            return m;
        }
    }
    return new Message();
}

本文不過多展示。

3.3 發(fā)送消息

在工作線程中通過調(diào)用 mHandler.sendMessage(myMessage); 方法來發(fā)送消息,這一步是消息入消息隊(duì)列操作,即將 Message 入 MessageQueue。

/**
 * 在當(dāng)前時(shí)間之前所有掛起的消息之后, 將消息推到消息隊(duì)列的末尾。它將該線程所關(guān)聯(lián)的 Handler 的 handleMessage 方法中被接收消息。
 * @return 如果信息成功加入到消息隊(duì)列中,返回 true,反之,入隊(duì)列失敗則返回 false, 失敗的原因通常是因?yàn)樘幚硐㈥?duì)列的“l(fā)ooper”正在退出。
 */
public final boolean sendMessage(@NonNull Message msg) {
    return sendMessageDelayed(msg, 0);
}

/**
 * 延時(shí) delayMillis 將消息入消息隊(duì)列,它將該線程所關(guān)聯(lián)的 Handler 的 handleMessage 方法中被接收消息。
 * @return 如果信息成功加入到消息隊(duì)列中,返回 true,反之,入隊(duì)列失敗則返回 false, 失敗的原因通常是因?yàn)樘幚硐㈥?duì)列的 Looper 正在退出。
 *         注意,true的結(jié)果并不意味著將處理該消息——如果 Looper 在消息的交付時(shí)間之前退出,則該消息將被刪除。
 */
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
    if (delayMillis < 0) {
        //默認(rèn) delayMillis = 0
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

/**
 * 在指定時(shí)間入隊(duì)列,深度睡眠的時(shí)間會(huì)增加額外的執(zhí)行延遲。它將該線程所關(guān)聯(lián)的 Handler 的 handleMessage 方法中被接收消息。
 * @param uptimeMillis 發(fā)送消息的絕對(duì)時(shí)間,使用{SystemClock # uptimeMillis}獲取。       
 * @return 如果信息成功加入到消息隊(duì)列中,返回 true,反之,入隊(duì)列失敗則返回 false, 失敗的原因通常是因?yàn)樘幚硐㈥?duì)列的 Looper 正在退出。
 *         注意,true的結(jié)果并不意味著將處理該消息——如果 Looper 在消息的交付時(shí)間之前退出,則該消息將被刪除。
 */
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
    //獲取當(dāng)前 Looper 對(duì)象的消息隊(duì)列
    MessageQueue queue = mQueue;
    //如果當(dāng)前 Looper 對(duì)象沒有消息隊(duì)列,則拋出異常,返回 false, 代表消息入隊(duì)列失敗
    if (queue == null) {
        RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}

//將消息放入消息隊(duì)列
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
        long uptimeMillis) {
    msg.target = this;
    msg.workSourceUid = ThreadLocalWorkSource.getUid();

    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

根據(jù)消息的處理時(shí)間入消息隊(duì)列
boolean enqueueMessage(Message msg, long when) {
    //獲得當(dāng)前的 Handler 對(duì)象,如果為 null, 則拋出異常
    if (msg.target == null) {
        throw new IllegalArgumentException("Message must have a target.");
    }
    //如果消息已經(jīng)被使用,即已經(jīng)入隊(duì)列,則拋出異常
    if (msg.isInUse()) {
        throw new IllegalStateException(msg + " This message is already in use.");
    }

    synchronized (this) {
        //如果 Looper 已經(jīng)退出,拋出異常,入隊(duì)列失敗,返回false
        if (mQuitting) {
            IllegalStateException e = new IllegalStateException(
                    msg.target + " sending message to a Handler on a dead thread");
            Log.w(TAG, e.getMessage(), e);
            msg.recycle();
            return false;
        }

        msg.markInUse();
        msg.when = when;
        Message p = mMessages;
        boolean needWake;
        //如果隊(duì)列里沒有消息,或者新消息的處理時(shí)間排在最前,即作為消息隊(duì)列新的隊(duì)頭插入消息隊(duì)列
        if (p == null || when == 0 || when < p.when) {
            //新的隊(duì)列頭部,如果隊(duì)列是 blocked 的狀態(tài)則需要喚醒該事件隊(duì)列。
            msg.next = p;
            mMessages = msg;
            needWake = mBlocked;
        } else {
            //插入處理時(shí)間插入到隊(duì)列的中間。通常我們不需要喚醒事件隊(duì)列,除非是隊(duì)列頭部的屏障,并且消息是隊(duì)列中最早的異步消息
            Message prev;
            for (;;) {
                prev = p;
                p = p.next;
                if (p == null || when < p.when) {
                    break;
                }
                if (needWake && p.isAsynchronous()) {
                    needWake = false;
                }
            }
            msg.next = p; // invariant: p == prev.next
            prev.next = msg;
        }

        // We can assume mPtr != 0 because mQuitting is false.
        if (needWake) {
            nativeWake(mPtr);
        }
    }
    return true;
}

3.4 消息循環(huán),派發(fā)消息

消息入 MessageQueue 隊(duì)列后,由 Looper 循環(huán)消息隊(duì)列,然后派發(fā)消息,如下所示:

/**
 * 在線程中運(yùn)行消息隊(duì)列,并確保調(diào)用 quit() 方法來結(jié)束消息循環(huán)
 */
public static void loop() {
    //獲取當(dāng)前線程關(guān)聯(lián)的 Looper 對(duì)象,如果該線程沒有關(guān)聯(lián)的 Looper 對(duì)象,則拋出異常
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    //獲取該 Looper 對(duì)象的消息隊(duì)列
    final MessageQueue queue = me.mQueue;

    //循環(huán)消息隊(duì)列
    for (;;) {
        //取出消息隊(duì)列中的消息對(duì)象,如果消息隊(duì)列為空,則 block 該線程。
        Message msg = queue.next(); // might block
        if (msg == null) {
            //沒有消息則表明消息隊(duì)列正在退出,解除消息循環(huán)
            return;
        }

        try {
            //消息對(duì)應(yīng)的 Handler 分發(fā)消息
            msg.target.dispatchMessage(msg);  
        } 
      
        //回收正在使用的消息
        msg.recycleUnchecked();
    }
}

/**
 * 處理系統(tǒng)消息
 */
public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        //如果 Message.callback 為空,執(zhí)行 handleMessage(msg),即回調(diào)復(fù)寫 handleMessage(msg) 方法。
        handleMessage(msg);
    }
}

/**
 * 回收可能正在使用的消息,由 MessageQueue 和 Looper 在處理排隊(duì)消息時(shí)在內(nèi)部使用。
 */
void recycleUnchecked() {
    //將消息標(biāo)記為正在使用,同時(shí)將其保留在回收的對(duì)象池中。并清楚其余所有細(xì)節(jié)
    flags = FLAG_IN_USE;
    what = 0;
    arg1 = 0;
    arg2 = 0;
    obj = null;
    replyTo = null;
    sendingUid = UID_NONE;
    workSourceUid = UID_NONE;
    when = 0;
    target = null;
    callback = null;
    data = null;
    ···
}

Looper 消息循環(huán),發(fā)送消息給指定的 Handler中,觸發(fā)我們覆寫的 handleMessage(Message) 方法。

至此,關(guān)于 Android Handler.sendMessage() 的源碼就分析完了。
其實(shí)分享文章的最大目的正是等待著有人指出我的錯(cuò)誤,如果你發(fā)現(xiàn)哪里有錯(cuò)誤,請(qǐng)毫無保留的指出即可,虛心請(qǐng)教。

另外,如果你覺得文章不錯(cuò),對(duì)你有所幫助,請(qǐng)給我點(diǎn)個(gè)贊,就當(dāng)鼓勵(lì),謝謝~Peace~!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容