handler.removeCallbacks(null)不能清除Runnable問題

??我們知道調(diào)用handler.removeCallbacksAndMessages(null);可以清空當(dāng)前handler的所有回調(diào)和所有消息。想當(dāng)然的認(rèn)為handler.removeCallbacks(null)可以清空所有回調(diào),實(shí)則不然。本文旨在探明其原因。
??首先,打開Handler.java,removeCallbacksAndMessages方法如下:

    /**
     * Remove any pending posts of callbacks and sent messages whose
     * <var>obj</var> is <var>token</var>.  If <var>token</var> is null,
     * all callbacks and messages will be removed.
     */
    public final void removeCallbacksAndMessages(Object token) {
        mQueue.removeCallbacksAndMessages(this, token);
    }

??可以看到,注釋中有提到參數(shù)為null時(shí)會(huì)移除所有回調(diào)和message,再看removeCallbacks方法,注釋中并沒有提到參數(shù)為null時(shí)會(huì)移除所有回調(diào)。

    /**
     * Remove any pending posts of Runnable r that are in the message queue.
     */
    public final void removeCallbacks(Runnable r)
    {
        mQueue.removeMessages(this, r, null);
    }

??如果還不確信的話,我們可以繼續(xù)向下探究。上文可以看到無(wú)論是在removeCallbacksAndMessages方法還是removeCallbacks方法中都繼續(xù)調(diào)用了mQueue對(duì)象中的removeCallbacksAndMessages和removeMessages方法,mQueue對(duì)象是MessageQueue類的實(shí)例,打開MessageQueue.java文件找到這兩個(gè)方法。首先是removeCallbacksAndMessages:

    void removeCallbacksAndMessages(Handler h, Object object) {
        if (h == null) {
            return;
        }

        synchronized (this) {
            Message p = mMessages;

            // Remove all messages at front.
            while (p != null && p.target == h
                    && (object == null || p.obj == object)) {
                Message n = p.next;
                mMessages = n;
                p.recycleUnchecked();
                p = n;
            }

            // Remove all messages after front.
            while (p != null) {
                Message n = p.next;
                if (n != null) {
                    if (n.target == h && (object == null || n.obj == object)) {
                        Message nn = n.next;
                        n.recycleUnchecked();
                        p.next = nn;
                        continue;
                    }
                }
                p = n;
            }
        }
    }

??從該方法可以看出,當(dāng)傳入的object對(duì)象為null時(shí),會(huì)循環(huán)回收掉所有message。在看removeMessages方法,當(dāng)傳入的Runnable為null時(shí),會(huì)直接退出,該方法如下:

  void removeMessages(Handler h, Runnable r, Object object) {
        if (h == null || r == null) {
            return;
        }

        synchronized (this) {
            Message p = mMessages;

            // Remove all messages at front.
            while (p != null && p.target == h && p.callback == r
                   && (object == null || p.obj == object)) {
                Message n = p.next;
                mMessages = n;
                p.recycleUnchecked();
                p = n;
            }

            // Remove all messages after front.
            while (p != null) {
                Message n = p.next;
                if (n != null) {
                    if (n.target == h && n.callback == r
                        && (object == null || n.obj == object)) {
                        Message nn = n.next;
                        n.recycleUnchecked();
                        p.next = nn;
                        continue;
                    }
                }
                p = n;
            }
        }
    }

??所以handler.removeCallbacks(null)不會(huì)移除任何回調(diào)。

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

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

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