Android-Handler源碼解析-Handler

Android-Handler源碼解析-Handler

源碼版本:

  • Handler:SDK-31

導(dǎo)航:

成員變量

// 是否發(fā)現(xiàn)(檢查)潛在的泄漏
private static final boolean FIND_POTENTIAL_LEAKS = false;
// Log的Tag
private static final String TAG = "Handler";
// 主線程Handler
private static Handler MAIN_THREAD_HANDLER = null;

// 此Handler的Looper
@UnsupportedAppUsage 
final Looper mLooper;

// 此Handler的消息隊(duì)列,來(lái)自Looper對(duì)象。
final MessageQueue mQueue;

// 此Handler分發(fā)消息時(shí),優(yōu)先處理消息的Callback。
@UnsupportedAppUsage
final Callback mCallback;

// 是否是異步Handler,即是否send或post的消息全部都是異步消息,默認(rèn)為false。
final boolean mAsynchronous;

// 跨進(jìn)程通信,消息發(fā)送者。
@UnsupportedAppUsage
IMessenger mMessenger;

說(shuō)明:

  1. Handler為什么需要持有Looper、MessageQueue,因?yàn)?code>Handler發(fā)送消息等操作需要知道發(fā)送到哪個(gè)MessageQueue,而MessageQueue需要從Looper中獲取,以便發(fā)出的消息能進(jìn)行輪詢分發(fā) 。
  2. Looper相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-Looper
  3. MessageQueue相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue。

創(chuàng)建Handler

想要使用Handler,首先要創(chuàng)建Handler,所以我們接下來(lái)看下它是如何被創(chuàng)建的。

new Handler()

默認(rèn)Looper

Handler()

@Deprecated
public Handler() {
    this(null, false);
}

Handler(Callback)

@Deprecated
public Handler(@Nullable Callback callback) {
    this(callback, false);
}   

Handler(Callback, boolean)

/** @hide */
public Handler(@Nullable Callback callback, boolean async) {
    if (FIND_POTENTIAL_LEAKS) {
        // 檢查潛在的泄漏
        final Class<? extends Handler> klass = getClass();
        if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                (klass.getModifiers() & Modifier.STATIC) == 0) {
            // 匿名類(lèi)、成員類(lèi)、局部類(lèi),并且不是靜態(tài)的,警告提示(以下Handler類(lèi)應(yīng)該是靜態(tài)的,否則可能會(huì)發(fā)生泄漏)。
            Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                klass.getCanonicalName());
        }
    }

    // 獲取當(dāng)前線程的Looper
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        // 當(dāng)前線程沒(méi)有Looper,則拋出異常提示(不能在沒(méi)有調(diào)用Looper.prepare()的線程中創(chuàng)建handler)。
        throw new RuntimeException(
            "Can't create handler inside thread " + Thread.currentThread()
                    + " that has not called Looper.prepare()");
    }
    // 獲取Looper的消息隊(duì)列
    mQueue = mLooper.mQueue;
    // 記錄CallBack
    mCallback = callback;
    // 記錄是否是異步的
    mAsynchronous = async;
}

以上構(gòu)造方法,使用默認(rèn)Looper當(dāng)前線程Looper)。如果這個(gè)線程沒(méi)有looper,則拋出異常。

說(shuō)明:

  1. Handler()、Handler(Callback)兩個(gè)構(gòu)造方法已經(jīng)被標(biāo)記@Deprecated(過(guò)時(shí)),因?yàn)樵?code>Handler構(gòu)造過(guò)程中隱式選擇一個(gè)Looper可能會(huì)導(dǎo)致錯(cuò)誤,其中操作會(huì)自動(dòng)丟失(如果Handler不需要新任務(wù)并退出)、崩潰(如果handler有時(shí)是在一個(gè)沒(méi)有激活Looper線程創(chuàng)建的),或者競(jìng)態(tài)條件,其中handler關(guān)聯(lián)的線程與作者預(yù)期的不符。相反,可以使用java.util.concurrent.Executor,或者使用Looper.getMainLooper,{link android.view.View#getHandler}或類(lèi)似工具顯式指定Looper。如果為了兼容性需要隱藏thread local行為,則使用new Handler(Looper.myLooper())讓讀者更清楚。
  2. Handler(Callback, boolean)兩個(gè)構(gòu)造方法已經(jīng)被標(biāo)記為@hide(隱藏),只能系統(tǒng)內(nèi)部使用。
  3. 使用默認(rèn)Looper當(dāng)前線程Looper),如果這個(gè)線程沒(méi)有looper,則拋出異常。
  4. 參數(shù)Callback,為此Handler分發(fā)消息時(shí),優(yōu)先處理消息的Callback,詳細(xì)見(jiàn)后面-分發(fā)Message。
  5. 參數(shù)async,為此Handler發(fā)送消息時(shí),是否全部發(fā)送異步/同步(默認(rèn)同步)消息,詳細(xì)見(jiàn)后面-發(fā)送Message。
  6. 異步消息表示不需要對(duì)同步消息進(jìn)行全局排序中斷事件。 異步消息不受MessageQueue.postSyncBarrier(long)引入的同步屏障的影響。
  7. MessageQueue同步屏障相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-同步屏障

指定Looper

Handler(Looper)

public Handler(@NonNull Looper looper) {
    this(looper, null, false);
}

Handler(Looper, Callback)

public Handler(@NonNull Looper looper, @Nullable Callback callback) {
    this(looper, callback, false);
}

Handler(Looper, Callback, boolean)

/** @hide */
@UnsupportedAppUsage
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

以上構(gòu)造方法,使用指定Looper不是默認(rèn)Looper。

說(shuō)明:

  1. Handler(Looper)Handler(Looper, Callback)兩個(gè)構(gòu)造方法未被標(biāo)記@Deprecated(過(guò)時(shí)),并使用指定Looper,推薦使用。
  2. Handler(Looper, Callback, boolean)構(gòu)造方法已經(jīng)被標(biāo)記為@hide(隱藏),只能系統(tǒng)內(nèi)部使用。

Handler.createAsync()

Handler.createAsync(Looper)

@NonNull
public static Handler createAsync(@NonNull Looper looper) {
    if (looper == null) throw new NullPointerException("looper must not be null");
    return new Handler(looper, null, true);
}

Handler.createAsync(Looper, Callback)

@NonNull
public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
    if (looper == null) throw new NullPointerException("looper must not be null");
    if (callback == null) throw new NullPointerException("callback must not be null");
    return new Handler(looper, callback, true);
}

Handler.createAsync()方法,為靜態(tài)方法,創(chuàng)建一個(gè)異步Handler,其發(fā)布Message不受同步障礙(如顯示vsync)的影響。

說(shuō)明:

  1. 發(fā)送到異步handler的消息可以保證彼此之間的順序,但不一定要按照來(lái)自其他Handlers的消息進(jìn)行排序。

小結(jié)

  1. 創(chuàng)建-同步Handler,分為未指定Looper指定Looper兩種方式創(chuàng)建。
  • 未指定Looper,則使用當(dāng)前線程Looper,不推薦使用。
  • 指定Looper推薦使用,構(gòu)造方法為Handler(Looper)、Handler(Looper, Callback)。
  1. 創(chuàng)建-異步Handler,使用Handler.createAsync(Looper)、Handler.createAsync(Looper, Callback)方法創(chuàng)建。

創(chuàng)建Message

想要使用Message,可以通過(guò)Handler創(chuàng)建Message,所以我們接下來(lái)看下它是如何被創(chuàng)建的。

obtainMessage()

@NonNull
public final Message obtainMessage() {
    return Message.obtain(this);
}

@NonNull
public final Message obtainMessage(int what) {
    return Message.obtain(this, what);
}

@NonNull
public final Message obtainMessage(int what, @Nullable Object obj) {
    return Message.obtain(this, what, obj);
}

@NonNull
public final Message obtainMessage(int what, int arg1, int arg2) {
    return Message.obtain(this, what, arg1, arg2);
}

@NonNull
public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
    return Message.obtain(this, what, arg1, arg2, obj);
}

以上obtainMessage()方法 ,從全局消息池返回一個(gè)新的消息。內(nèi)部使用Message.obtain()方法創(chuàng)建消息,并將其Messagetarget為當(dāng)前Handler

說(shuō)明:

  1. Message.obtain()相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-Message-創(chuàng)建Message。

小結(jié)

  1. handler.obtainMessage()方法,使用Message.obtain()方法創(chuàng)建消息,并將其Messagetarget為當(dāng)前Handler。

發(fā)送Message

Message創(chuàng)建好后,便可以發(fā)送消息了,Handler除了可以通過(guò)sendMessage()方法發(fā)送消息,還可以通過(guò)post()方法執(zhí)行指定Callback任務(wù),所以我們接下來(lái)看下它們是如何被發(fā)送的。

send-Message

sendMessage()

public final boolean sendMessage(@NonNull Message msg) {
    return sendMessageDelayed(msg, 0);
}

sendEmptyMessage()

public final boolean sendEmptyMessage(int what) {
    return sendEmptyMessageDelayed(what, 0);
}

sendEmptyMessageDelayed()

public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
    Message msg = Message.obtain();
    msg.what = what;
    return sendMessageDelayed(msg, delayMillis);
}

sendEmptyMessageAtTime()

public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
    Message msg = Message.obtain();
    msg.what = what;
    return sendMessageAtTime(msg, uptimeMillis);
}

sendMessageDelayed()

public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

sendMessageAtTime()

public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    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);
}

sendMessageAtFrontOfQueue()

public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
    MessageQueue queue = mQueue;
    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, 0);
}

以上方法,為發(fā)送立即消息、發(fā)送延遲消息、發(fā)送指定時(shí)刻消息將消息排在消息隊(duì)列的前面。

說(shuō)明:

  1. sendMessage()、sendEmptyMessage()發(fā)送立即消息消息,sendMessageDelayed()、sendEmptyMessageDelayed()發(fā)送延遲消息消息,sendMessageAtTime()發(fā)送指定時(shí)刻消息,sendMessageAtFrontOfQueue()將消息排在消息隊(duì)列的前面。
  2. sendMessageAtFrontOfQueue(),為將消息排在消息隊(duì)列的前面,以便在消息loop下一次迭代中處理。此方法僅用于非常特殊的情況——它很容易使消息隊(duì)列挨餓、導(dǎo)致排序問(wèn)題產(chǎn)生其它意想不到的副作用
  3. 發(fā)送立即消息、發(fā)送延遲消息指定時(shí)刻發(fā)送、將消息排在消息隊(duì)列的前面,他們最終調(diào)用的都是enqueueMessage()方法。

我們接下來(lái)看下enqueueMessage()方法。

enqueueMessage()

private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
        long uptimeMillis) {
    // 指定Message的Handler為此Handler
    msg.target = this;
    msg.workSourceUid = ThreadLocalWorkSource.getUid();

    // 如果此Handler是異步的,則發(fā)送的所有消息都是異步的。
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    // 使用MessageQueue將消息加入到消息隊(duì)列中
    return queue.enqueueMessage(msg, uptimeMillis); 
}

enqueueMessage()方法,為將Message加入到MessageQueue中。

說(shuō)明:

  1. 指定MessagetargetHandler,使MessageHandler關(guān)聯(lián),以便使用Handler處理Message。
  2. 如果此Handler異步的,則發(fā)送的所有消息都是異步的。
  3. uptimeMillis參數(shù)為消息執(zhí)行時(shí)刻,立即執(zhí)行的為SystemClock.uptimeMillis(),延時(shí)執(zhí)行的為SystemClock.uptimeMillis() + delayMillis ,指定時(shí)刻發(fā)送的為指定的將消息排在消息隊(duì)列的前面的為0。
  4. MessageQueue入隊(duì)消息相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-入隊(duì)Message。

post-Callback

post()

public final boolean post(@NonNull Runnable r) {
   return  sendMessageDelayed(getPostMessage(r), 0);
}

postAtTime()

public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
    return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}

public final boolean postAtTime(@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
    return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}

postDelayed()

public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
    return sendMessageDelayed(getPostMessage(r), delayMillis);
}

public final boolean postDelayed(@NonNull Runnable r, @Nullable Object token, long delayMillis) {
    return sendMessageDelayed(getPostMessage(r, token), delayMillis);
}

postAtFrontOfQueue()

public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
    return sendMessageAtFrontOfQueue(getPostMessage(r));
}

以上方法,為執(zhí)行指定Callback任務(wù),由Runnable實(shí)現(xiàn)。底層也是通過(guò)getPostMessage()方法將Runnable包裝Message然后調(diào)用對(duì)應(yīng)發(fā)送消息的方法進(jìn)行發(fā)送,發(fā)送消息詳細(xì)看上面的-send-Message。

接下來(lái)我們來(lái)看一下getPostMessage()方法的實(shí)現(xiàn)。

getPostMessage()

private static Message getPostMessage(Runnable r) {
    // 使用復(fù)用獲取新的Message
    Message m = Message.obtain();
    // 將Runnable保存到Message的callback中
    m.callback = r;
    return m;
}

@UnsupportedAppUsage
private static Message getPostMessage(Runnable r, Object token) {
    Message m = Message.obtain();
    m.obj = token;
    m.callback = r;
    return m;
}

getPostMessage()方法,使用復(fù)用機(jī)制獲取新的Message,并將Runnable保存到Messagecallback中。

小結(jié)

  1. 發(fā)送消息分為send-Message、post-Callbackpost-Callback底層也是通過(guò)send-Message進(jìn)行發(fā)送(將Runnable保存到Messagecallback中)。
  2. sendMessageAtFrontOfQueue()、postAtFrontOfQueue(),方法為將消息排在消息隊(duì)列的前面,會(huì)使原來(lái)有序的隊(duì)列變?yōu)?strong>無(wú)序的,謹(jǐn)慎使用。
  3. 通過(guò)handler發(fā)送的消息,最終都會(huì)將MessageHandler關(guān)聯(lián),以便使用Handler處理Message。
  4. 如果此Handler異步的,則發(fā)送的所有消息都是異步的。

分發(fā)Message

當(dāng)Looper.loop()方法開(kāi)啟后,并且此LooperMessageQueuenext()方法返回一個(gè)Message后,會(huì)調(diào)用HandlerdispatchMessage()方法,代碼如下。

Loop->loopOnce()

private static boolean loopOnce(final Looper me,
            final long ident, final int thresholdOverride) {
        Message msg = me.mQueue.next(); // might block
        ...
        // 調(diào)用Handler分發(fā)消息
        msg.target.dispatchMessage(msg);
        ...
    }

接下來(lái)我們來(lái)看一下HandlerdispatchMessage()方法。

dispatchMessage()

Handler->dispatchMessage()

public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        // 處理Callback
        handleCallback(msg);
    } else {
        // 處理Message
        if (mCallback != null) {
            // handler的Callback不為空,優(yōu)先它處理。
            if (mCallback.handleMessage(msg)) {
                // 返回true,表示handler的Callback已經(jīng)處理,不再需要handleMessage()方法處理。
                return;
            }
        }
        // 使用handleMessage方法處理
        handleMessage(msg);
    }
}

dispatchMessage()方法,為分發(fā)消息,分為處理Callback處理Message,而的處理Message優(yōu)先handlerCallback處理,其次再handleMessage()方法處理。

說(shuō)明:

  1. dispatchMessage()方法為public并且不是final,所以可以被覆寫(xiě),一般不覆寫(xiě)此方法。

接下來(lái)我們先來(lái)看一下處理CallbackhandleCallback()方法。

handleCallback()

private static void handleCallback(Message message) {
    // 調(diào)用callback.run()方法(即runnable.run()方法)執(zhí)行
    message.callback.run();
}

handleCallback()方法,直接調(diào)用messagecallback(即Runnable)的run()方法執(zhí)行。

接下來(lái)我們?cè)賮?lái)看一下優(yōu)先處理MessageHandler.Callback類(lèi),其次再來(lái)看一下其次處理handleMessage()方法。

Handler.Callback類(lèi)

public interface Callback {
    /**
     * @return 如果不需要進(jìn)一步處理,則為T(mén)rue。
     */
    boolean handleMessage(@NonNull Message msg);
}

如果handler.mCallback有設(shè)置值,則優(yōu)先它來(lái)處理,并且handleMessage()方法返回true,則不再需要handleMessage()方法處理。

handleMessage()

public void handleMessage(@NonNull Message msg) {
}

handleMessage()方法,為處理消息,我們可以通過(guò)Messagewhat的值來(lái)區(qū)分,來(lái)實(shí)現(xiàn)自己的邏輯。

說(shuō)明:

  1. handleMessage()方法為public并且不是final,所以可以被覆寫(xiě),一般覆寫(xiě)此方法。

小結(jié)

  1. 分發(fā)Message,它是通過(guò)HandlerdispatchMessage()方法進(jìn)行分發(fā)處理。
  2. 分發(fā)Message,它分為處理Callback、處理Message
    2.1.處理Callback,直接調(diào)用callback(即Runnable)的run()方法執(zhí)行。
    2.2.處理Message,優(yōu)先handlerCallback處理,其次再handleMessage()方法處理。
  3. dispatchMessage()、handleMessage()方法均可以被覆寫(xiě),一般只覆寫(xiě)handleMessage()方法即可。

移除Messages、Callbacks

removeMessages()

public final void removeMessages(int what) {
    mQueue.removeMessages(this, what, null);
}

public final void removeMessages(int what, @Nullable Object object) {
    mQueue.removeMessages(this, what, object);
}

removeCallbacks()

public final void removeCallbacks(@NonNull Runnable r) {
    mQueue.removeMessages(this, r, null);
}

public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
    mQueue.removeMessages(this, r, token);
}

removeCallbacksAndMessages()

public final void removeCallbacksAndMessages(@Nullable Object token) {
    mQueue.removeCallbacksAndMessages(this, token);
}

以上方法,為移除指定whatMessage或指定runnableCallbacks,全部都是通過(guò)調(diào)用MessageQueueremoveXX方法進(jìn)行移除。

說(shuō)明:

  1. MessageQueue移除消息相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-移除Message。

小結(jié)

  1. 移除Messages、Callbacks,removeMessages()、removeCallbacks()、removeCallbacksAndMessages()方法,分別為移除所有符合條件的Messages、Callbacks。

是否有Messages、Callbacks

hasMessages()

public final boolean hasMessages(int what) {
    return mQueue.hasMessages(this, what, null);
}

hasCallbacks()

public final boolean hasCallbacks(@NonNull Runnable r) {
    return mQueue.hasMessages(this, r, null);
}

hasMessagesOrCallbacks()

public final boolean hasMessagesOrCallbacks() {
    return mQueue.hasMessages(this);
}

以上方法,為判斷是否有指定whatMessage或指定runnableCallbacks,全部都是通過(guò)調(diào)用MessageQueuehasMessages方法進(jìn)行判斷。

說(shuō)明:

  1. MessageQueue是否有消息相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-是否有Message。

小結(jié)

  1. 是否有Messages、CallbackshasMessages()、hasCallbacks()、hasMessagesOrCallbacks()方法,分別為判斷是否有符合條件的Messages、Callbacks。

其它

getMessageName()

public String getMessageName(@NonNull Message message) {
    if (message.callback != null) {
        // 是Callback類(lèi)型,返回此Callback(即Runnable)的類(lèi)名。
        return message.callback.getClass().getName();
    }
    // 是Message類(lèi)型,返回此Message的what的十六進(jìn)制。
    return "0x" + Integer.toHexString(message.what);
}

獲取表示指定Message名稱(chēng)字符串。默認(rèn)實(shí)現(xiàn),是Callback類(lèi)型返回此Callback(即Runnable)的類(lèi)名,是Message類(lèi)型返回此Messagewhat十六進(jìn)制。

getLooper()

@NonNull
public final Looper getLooper() {
    return mLooper;
}

獲取HandlerLooper對(duì)象

dump()

public final void dump(@NonNull Printer pw, @NonNull String prefix) {
    pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
    if (mLooper == null) {
        pw.println(prefix + "looper uninitialized");
    } else {
        mLooper.dump(pw, prefix + "  ");
    }
}

轉(zhuǎn)儲(chǔ)looper的狀態(tài),以進(jìn)行調(diào)試。如果Looper為空,直接打印,否則調(diào)用Looperdump()方法。

說(shuō)明:

  1. Looper轉(zhuǎn)儲(chǔ)的相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-Looper-其它。

總結(jié)

以上就是Handler源碼的Handler源碼部分,Handler其它源碼部分看下面導(dǎo)航。之后會(huì)出其它Android源碼系列,請(qǐng)及時(shí)關(guān)注。如果你有什么問(wèn)題,大家評(píng)論區(qū)見(jiàn)!

導(dǎo)航:

最后推薦一下我的網(wǎng)站,開(kāi)發(fā)者的技術(shù)博客: devbolg.cn ,目前包含android相關(guān)的技術(shù),之后會(huì)面向全部開(kāi)發(fā)者,歡迎大家來(lái)體驗(yàn)!

?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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