最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android移除Message的方法分享

 更新時(shí)間:2022年10月11日 16:02:47   作者:長(zhǎng)安皈故里  
本篇文章主要介紹MessageQueue提供的各種移除Message的方法,大概有八九個(gè),接下來(lái)會(huì)對(duì)其中比較典型的移除方法進(jìn)行詳細(xì)分析,需要的可以參考一下

退出Looper循環(huán)移除Message的兩種方式

大家都知道,消息機(jī)制在Android系統(tǒng)運(yùn)行中扮演著重要的角色,通過(guò)消息發(fā)送、添加消息隊(duì)列、分發(fā)等一整個(gè)流程驅(qū)動(dòng)Android的運(yùn)行。

主線程是在ActivityThread.main()中調(diào)用了Looper.loop(),開(kāi)啟消息循環(huán)遍歷執(zhí)行的,這個(gè)消息循環(huán)可以退出嗎,接下來(lái)我們仔細(xì)研究下;

上源碼:

void quit(boolean safe) {
    //1.不允許退出就拋出異常
    if (!mQuitAllowed) {
        throw new IllegalStateException("Main thread not allowed to quit.");
    }

    synchronized (this) {
        if (mQuitting) {
            return;
        }
        //2.
        mQuitting = true;

        if (safe) {
            //3.安全退出
            removeAllFutureMessagesLocked();
        } else {
            //4.非安全退出
            removeAllMessagesLocked();
        }

        nativeWake(mPtr);
    }
}

1.對(duì)于主線程而言,mQuitAllowed的值是false,也就是說(shuō)主線程的Looper循環(huán)不允許手動(dòng)調(diào)用quit()退出,否則就拋出異常;

2.將退出標(biāo)識(shí)mQuitting置為true,這樣當(dāng)從消息隊(duì)列中取消息時(shí),會(huì)先判斷下這個(gè)標(biāo)識(shí)mQuitting是否為true,是就會(huì)經(jīng)過(guò)調(diào)用鏈一步步退出Looper消息循環(huán);

3.安全的退出Looper開(kāi)啟的消息循環(huán),深入下removeAllFutureMessagesLocked()看下:

private void removeAllFutureMessagesLocked() {
    final long now = SystemClock.uptimeMillis();
    Message p = mMessages;
    if (p != null) {
        //1.
        if (p.when > now) {
            removeAllMessagesLocked();
        } else {
            Message n;
            for (;;) {
                n = p.next;
                if (n == null) {
                    return;
                }
                if (n.when > now) {
                    break;
                }
                p = n;
            }
            p.next = null;
            do {
                p = n;
                n = p.next;
                p.recycleUnchecked();
            } while (n != null);
        }
    }
}
  • 首先如果消息隊(duì)列隊(duì)頭的消息的執(zhí)行時(shí)間戳when大于當(dāng)前時(shí)間,則直接調(diào)用 removeAllMessagesLocked()方法移除所有的消息 ,這個(gè)方法之后會(huì)講解;
  • 上面條件不滿足,就不斷的遍歷消息隊(duì)列,直到找出執(zhí)行時(shí)間戳大于當(dāng)前時(shí)間的消息,然后通過(guò)do-while()循環(huán),將該消息及之后的消息全部進(jìn)行回收處理,放入到我們之前講解的對(duì)象池;

4.非安全的退出是直接調(diào)用了removeAllMessagesLocked()方法,我們深入看下:

private void removeAllMessagesLocked() {
    Message p = mMessages;
    while (p != null) {
        Message n = p.next;
        p.recycleUnchecked();
        p = n;
    }
    mMessages = null;
}

可以看到這種移除方法大殺特殺,不會(huì)去比較消息執(zhí)行的時(shí)間戳啥的,直接全部干翻回收到消息對(duì)象池,簡(jiǎn)單粗暴。

這里對(duì)于非安全和安全退出Looper循環(huán)做個(gè)總結(jié):

安全退出Looper循環(huán)只會(huì)移除回收大于當(dāng)前時(shí)間戳的消息,而不大于當(dāng)前時(shí)間戳的消息都可以保證正常執(zhí)行;而非安全的退出比較粗暴,直接清空回收整個(gè)消息隊(duì)列。這兩種情況大家根據(jù)需要選擇性的使用。

removeXXXMessages()移除指定的消息

可以看到移除消息的方法一大堆,比如通過(guò)指定Messagewhat、obj、callback等信息移除指定Message,這里我們就以removeCallbacksAndMessages()舉例。

removeCallbacksAndMessages()方法大家應(yīng)該很梳理,是我們?cè)谀硞€(gè)界面中使用Handler發(fā)送消息時(shí),避免發(fā)生內(nèi)存泄漏的一種方式,接下來(lái)我們深入分析下:

void removeCallbacksAndMessages(Handler h, Object object) {
    //...
    synchronized (this) {
        Message p = mMessages;
        //1.從頭移除消息
        while (p != null && p.target == h
                && (object == null || p.obj == object)) {
            Message n = p.next;
            mMessages = n;
            p.recycleUnchecked();
            p = n;
        }

        //2. 從中間移除消息
        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;
        }
    }
}

如果這個(gè)方法傳入的object不為null,就會(huì)移除指定的Message,如果指定為null,就會(huì)移除傳入的Handler發(fā)送的所有消息。

上面的源碼中可以看到,移除Message分為兩個(gè)部分,為什么要這么做呢?

假設(shè)消息隊(duì)列中存在下面一系列消息集合:

如果Message1滿足移除條件,那么直接回收這條消息,并將消息隊(duì)列的隊(duì)頭指針指向下一個(gè)消息即可mMessages = mMessages.next,對(duì)應(yīng)上面源碼中前半部分移除消息的邏輯。

但假設(shè)Message1不滿足移除條件,Message2滿足移除條件,這樣移除就不是直接將消息隊(duì)列的隊(duì)頭指針指向next即下一個(gè)Message就能簡(jiǎn)單解決的。

正確的做法是:先要保存Message1,然后通過(guò)Message2.next獲取到Message3的引用保存起來(lái),最后將Message1.next指向上面保存的Message3引用。這部分就對(duì)應(yīng)上面源碼中后半部分移除消息的邏輯。

總結(jié)

本篇文章主要是對(duì)MessageQueue提供的各種移除Message的方法做了一個(gè)簡(jiǎn)單的介紹,方法很多主要分為兩種:移除指定標(biāo)識(shí)的Handler發(fā)送的Message和移除所有Handler發(fā)送的Message

到此這篇關(guān)于Android移除Message的方法分享的文章就介紹到這了,更多相關(guān)Android移除Message內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android獲取當(dāng)前手機(jī)網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機(jī)型號(hào)、版本號(hào)代碼

    Android獲取當(dāng)前手機(jī)網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機(jī)型號(hào)、版本號(hào)代碼

    這篇文章主要介紹了Android獲取當(dāng)前手機(jī)網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機(jī)型號(hào)、版本號(hào)的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • AndriodStudio使用listview實(shí)現(xiàn)簡(jiǎn)單圖書(shū)管理

    AndriodStudio使用listview實(shí)現(xiàn)簡(jiǎn)單圖書(shū)管理

    這篇文章主要為大家詳細(xì)介紹了AndriodStudio使用listview實(shí)現(xiàn)簡(jiǎn)單圖書(shū)管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Android自定義View繪制貝塞爾曲線實(shí)現(xiàn)流程

    Android自定義View繪制貝塞爾曲線實(shí)現(xiàn)流程

    貝塞爾曲線的本質(zhì)是通過(guò)數(shù)學(xué)計(jì)算的公式來(lái)繪制平滑的曲線,分為一階,二階,三階及多階。但是這里不講數(shù)學(xué)公式和驗(yàn)證,那些偉大的數(shù)學(xué)家已經(jīng)證明過(guò)了,所以就只講講Android開(kāi)發(fā)中的運(yùn)用吧
    2022-11-11
  • Android使用WebSocket實(shí)現(xiàn)多人游戲

    Android使用WebSocket實(shí)現(xiàn)多人游戲

    WebSocket 是 HTML5 一種新的協(xié)議。實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,下面通過(guò)本文給大家分享Android使用WebSocket實(shí)現(xiàn)多人游戲,需要的朋友參考下吧
    2017-11-11
  • Android Jetpack組件中LiveData的優(yōu)劣

    Android Jetpack組件中LiveData的優(yōu)劣

    LiveData是Jetpack組件的一部分,更多的時(shí)候是搭配ViewModel來(lái)使用,相對(duì)于Observable,LiveData的最大優(yōu)勢(shì)是其具有生命感知的,換句話說(shuō),LiveData可以保證只有在組件(?Activity、Fragment、Service)處于活動(dòng)生命周期狀態(tài)的時(shí)候才會(huì)更新數(shù)據(jù)
    2023-04-04
  • android Listview模擬聊天界面

    android Listview模擬聊天界面

    這篇文章主要為大家詳細(xì)介紹了android Listview模擬聊天界面的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android ViewFlipper的簡(jiǎn)單使用

    Android ViewFlipper的簡(jiǎn)單使用

    這篇文章主要為大家詳細(xì)介紹了Android ViewFlipper的簡(jiǎn)單使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 學(xué)習(xí)使用Material Design控件(一)

    學(xué)習(xí)使用Material Design控件(一)

    這篇文章主要為大家介紹了學(xué)習(xí)使用Material Design控件的詳細(xì)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 解決Android使用Handler造成內(nèi)存泄露問(wèn)題

    解決Android使用Handler造成內(nèi)存泄露問(wèn)題

    內(nèi)存泄露的危害就是會(huì)使虛擬機(jī)占用內(nèi)存過(guò)高,導(dǎo)致OOM(內(nèi)存溢出),程序出錯(cuò)。接下來(lái)通過(guò)本文給大家分享Android使用Handler造成內(nèi)存泄露問(wèn)題及解決方法,一起看看吧
    2017-08-08
  • Android修改源碼解決Alertdialog觸摸對(duì)話框邊緣消失的問(wèn)題

    Android修改源碼解決Alertdialog觸摸對(duì)話框邊緣消失的問(wèn)題

    在開(kāi)發(fā)的時(shí)候遇到一個(gè)問(wèn)題,就是一觸摸對(duì)話框邊緣外部,對(duì)話框會(huì)自動(dòng)消失。這個(gè)問(wèn)題很糾結(jié)啊,查找了一下發(fā)現(xiàn)從Android 4.0開(kāi)始,AlertDialog有了變化,就是在觸摸對(duì)話框邊緣外部,對(duì)話框會(huì)自動(dòng)消失,查了源碼,找到解決辦法如下
    2013-11-11

最新評(píng)論

柳州市| 新龙县| 汝州市| 承德市| 依兰县| 汝阳县| 太保市| 肇东市| 区。| 兖州市| 郸城县| 凯里市| 灵宝市| 榆社县| 裕民县| 沙河市| 东乡族自治县| 成都市| 黄冈市| 安新县| 买车| 韩城市| 武胜县| 驻马店市| 都安| 济源市| 营口市| 时尚| 景德镇市| 陇川县| 桂阳县| 宁夏| 若羌县| 凭祥市| 新郑市| 沽源县| 湖北省| 阆中市| 阜康市| 长治市| 柳江县|