日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Android開發使用Message對象分發必備知識點詳解_Android

作者:長安皈故里 ? 更新時間: 2022-11-24 編程語言

Message的創建

消息Message一般不支持大家直接通過new的方式進行創建的,因為Message作為Android系統中使用頻率非常高的一個對象,如果每次都泛濫的直接創建一個新的,對性能是有一定影響的,而通過對象池的方式進行復用 ,則是非常好的一種方式。

Message中就提供了這樣的一個對象池(最大緩存消息數量為50):

通過鏈表的形式將一個個待復用的緩存Message連接起來。并且提供了obtain()方法負責從對象池中獲取一個Message

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();
}

當消息調度完畢時,會通過recycleUnchecked()方法進行回收并放入到對象池:

void recycleUnchecked() {
    flags = FLAG_IN_USE;
    what = 0;
    arg1 = 0;
    arg2 = 0;
    obj = null;
    ...
    synchronized (sPoolSync) {
        if (sPoolSize < MAX_POOL_SIZE) {
            next = sPool;
            sPool = this;
            sPoolSize++;
        }
    }
}

重置要回收的Message的各個成員屬性,然后添加到對象池sPool。

消息分發執行的三種方式

消息調度分發最終是在Looper.loopOnce()中執行,我們看下源碼:

private static boolean loopOnce(final Looper me,
        final long ident, final int thresholdOverride) {
    Message msg = me.mQueue.next(); // might block
    if (msg == null) {
        return false;
    }
    try {
        msg.target.dispatchMessage(msg);
    }
    msg.recycleUnchecked();
    return true;
}

核心就是msg.target.dispatchMessage(),我們看下具體的方法邏輯:

public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}

源碼一目了然,接下來我們一個個的進行分析:

  • 先檢測Messagecallback是否為null,不為null就執行callbackrun方法調度執行,這個一般是如何傳入的呢:
public final boolean post(@NonNull Runnable r) {
   return  sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

很熟悉的post()方法就并不再過多介紹了。

  • 然后檢測HandermCallback是否為null,不為null就執行mCallback.handleMessage(),這個是什么時候傳入的呢:
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

通過Handler構造方法時作為構造參數傳入,可以選擇性使用。

  • 上面都不滿足,就調用Handler自身的handleMessage()方法調度執行,這也是我們常用的消息執行的一種方式,一般都是創建Handler對象時重寫這個該方法:
fun test333() {
    val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
        }
    }
}

以上三種消息分發方式第一種和第三種使用的頻率比較高,第二種這種方式可以作為一種hook的手段攔截某些消息的原本調度邏輯,實現功能增強。

比如Activity、Service等組件的調度是通過ApplicationThread通過Handler分發到主線程進行調度執行,如果你想監聽其生命周期,就可以通過上面的第二種方式結合反射給負責分發的Handler注入一個mCallback屬性值。

總結

本篇文章主要是介紹了Message創建的正確方式,以及其如何在Handler中調度分發的,每個流程是什么,希望能給你帶來幫助。

原文鏈接:https://juejin.cn/post/7151929832698281991

欄目分類
最近更新