iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android移除Message的方法分享
  • 301
分享到

Android移除Message的方法分享

Android移除Message方法Android移除MessageAndroidMessage 2022-11-13 18:11:45 301人浏览 薄情痞子
摘要

目录退出Looper循环移除Message的两种方式removeXXXMessages()移除指定的消息总结退出Looper循环移除Message的两种方式 大家都知道,消息机制在A

退出Looper循环移除Message的两种方式

大家都知道,消息机制在Android系统运行中扮演着重要的角色,通过消息发送、添加消息队列、分发等一整个流程驱动Android的运行。

线程是在ActivityThread.main()中调用了Looper.loop(),开启消息循环遍历执行的,这个消息循环可以退出吗,接下来我们仔细研究下;

源码

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.对于主线程而言,mQuitAllowed的值是false,也就是说主线程的Looper循环不允许手动调用quit()退出,否则就抛出异常;

2.将退出标识mQuitting置为true,这样当从消息队列中取消息时,会先判断下这个标识mQuitting是否为true,是就会经过调用链一步步退出Looper消息循环;

3.安全的退出Looper开启的消息循环,深入下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);
        }
    }
}
  • 首先如果消息队列队头的消息的执行时间戳when大于当前时间,则直接调用 removeAllMessagesLocked()方法移除所有的消息 ,这个方法之后会讲解;
  • 上面条件不满足,就不断的遍历消息队列,直到找出执行时间戳大于当前时间的消息,然后通过do-while()循环,将该消息及之后的消息全部进行回收处理,放入到我们之前讲解的对象池;

4.非安全的退出是直接调用了removeAllMessagesLocked()方法,我们深入看下:

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

可以看到这种移除方法大杀特杀,不会去比较消息执行的时间戳啥的,直接全部干翻回收到消息对象池,简单粗暴。

这里对于非安全和安全退出Looper循环做个总结:

安全退出Looper循环只会移除回收大于当前时间戳的消息,而不大于当前时间戳的消息都可以保证正常执行;而非安全的退出比较粗暴,直接清空回收整个消息队列。这两种情况大家根据需要选择性的使用。

removeXXXMessages()移除指定的消息

可以看到移除消息的方法一大堆,比如通过指定Messagewhatobjcallback等信息移除指定Message,这里我们就以removeCallbacksAndMessages()举例。

removeCallbacksAndMessages()方法大家应该很梳理,是我们在某个界面中使用Handler发送消息时,避免发生内存泄漏的一种方式,接下来我们深入分析下:

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

如果这个方法传入的object不为null,就会移除指定的Message,如果指定为null,就会移除传入的Handler发送的所有消息。

上面的源码中可以看到,移除Message分为两个部分,为什么要这么做呢?

假设消息队列中存在下面一系列消息集合

如果Message1满足移除条件,那么直接回收这条消息,并将消息队列的队头指针指向下一个消息即可mMessages = mMessages.next,对应上面源码中前半部分移除消息的逻辑。

但假设Message1不满足移除条件,Message2满足移除条件,这样移除就不是直接将消息队列的队头指针指向next即下一个Message就能简单解决的。

正确的做法是:先要保存Message1,然后通过Message2.next获取到Message3的引用保存起来,最后将Message1.next指向上面保存的Message3引用。这部分就对应上面源码中后半部分移除消息的逻辑。

总结

本篇文章主要是对MessageQueue提供的各种移除Message的方法做了一个简单的介绍,方法很多主要分为两种:移除指定标识的Handler发送的Message和移除所有Handler发送的Message

到此这篇关于Android移除Message的方法分享的文章就介绍到这了,更多相关Android移除Message内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android移除Message的方法分享

本文链接: https://www.lsjlt.com/news/169193.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android移除Message的方法分享
    目录退出Looper循环移除Message的两种方式removeXXXMessages()移除指定的消息总结退出Looper循环移除Message的两种方式 大家都知道,消息机制在A...
    99+
    2022-11-13
    Android移除Message方法 Android移除Message Android Message
  • Android 移除弹窗方案
    系统裁剪–移除系统弹窗通知 前一阵子被拉去评估一个需求,有个物联网产品是建立在Android平台基础上的,Android中的一些弹窗提示不需要,客户说一定要移除掉。 首先有哪些需要去掉呢?Androi...
    99+
    2023-09-17
    android java
  • 分享Golang中的数组删除方法
    Golang数组删除技巧分享 在日常开发中,我们经常会遇到需要对数组进行删除操作的情况。对于 Golang 这样一门强类型的语言,删除数组元素可能并不像其他语言那样直接。本文将分享一些...
    99+
    2024-02-25
    golang 技巧分享 数组删除
  • Java List移除相应元素的超简洁写法分享
    目录List移除相应元素的超简洁写法好了上代码Java List 删除元素1.删除后元素后,i-12.反向删除3.使用迭代器删除(iterator)(推荐)4.赋值给新的listLi...
    99+
    2024-04-02
  • css清除浮动的几种方法分享
    本篇内容主要讲解“css清除浮动的几种方法分享”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“css清除浮动的几种方法分享”吧!加入一个空的同类元素,然后设置元素css属性  ...
    99+
    2023-06-08
  • Android handle-message的发送与处理方法是什么
    在Android中,`Handler`类用于发送和处理消息。发送消息:1. 创建一个`Handler`对象。2. 创建一个`Mess...
    99+
    2023-08-11
    Android
  • android杂记:C++文件的添加log方法分享
    1.添加头文件复制代码 代码如下:#include <utils/Log.h>   //或者  #include <cutils/Lo...
    99+
    2022-11-15
    C++ 文件 log
  • 将mysql服务移除的方法
    将mysql服务移除的方法?这个问题可能是我们日常学习或工作经常见到的。希望通过这个问题能让你收获颇深。下面是小编给大家带来的参考内容,让我们一起来看看吧!将mysql服务移除的方法:1、进入“控制面板-&...
    99+
    2024-04-02
  • 基于Spring Boot排除自动配置的方法分享
    这篇文章主要讲解了“基于Spring Boot排除自动配置的方法分享”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于Spring Boot排除自动配置的方法分享”吧!Spring Boot...
    99+
    2023-06-20
  • php怎么删除数组的值?多种方法分享
    删除数组的值是 PHP 编程中常见的任务,因为数组通常是存储多个值的一维或二维数据结构。并且,有时候在代码执行过程中,需要从数组中删除某些元素,以更新或修改数组的内容。在 PHP 中,删除数组值的方法有很多。本文将介绍一些最常用的方法。使用...
    99+
    2023-05-14
    php数组 php
  • mongodb清除连接和日志的正确方法分享
    目录前言关闭current的方法一:关闭current的方法二:日志去重script导出数据总结前言 最近在做并发,服务器卡死了。 感觉是pymongo未能完全close掉和mong...
    99+
    2024-04-02
  • Android开发中实现登录微信与分享的方法
    本篇文章给大家分享的是有关Android开发中实现登录微信与分享的方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。第一步:申请你的AppID;第二步:依赖dependenci...
    99+
    2023-05-31
    android roi
  • php移除第一个元素的方法
    小编给大家分享一下php移除第一个元素的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!php移除第一个元素的方法:首先创建一个PHP示例文件;然后定义一个数组...
    99+
    2023-06-06
  • php怎么去除字符串的开头部分?三种方法分享
    PHP中提供了一些便捷的方法,可以去除字符串的开头部分。本文将介绍三种常用的方法:substr,ltrim和preg_replace。substrsubstr函数可以从字符串的某个位置开始截取一定长度的字符。如果要去除开头的字符,可以设置长...
    99+
    2023-05-14
  • POI的常用方法分享
    这篇文章主要讲解了“POI的常用方法分享”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“POI的常用方法分享”吧!public static void main(String[] args) ...
    99+
    2023-06-03
  • Linux系统分区的方法分享
    本篇内容主要讲解“Linux系统分区的方法分享”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux系统分区的方法分享”吧!Linux分区方法,不同的人有不同的方法,反正没有统一的方法。在分区...
    99+
    2023-06-13
  • Android加载长图的多种方案分享
    目录背景介绍方案1:WebView加载渲染方案2:BitmapRegionDecoder方案3:SubsamplingScaleImageView方案4:Glide+Subsampl...
    99+
    2024-04-02
  • 常见的移动端前端适配方案分享
    今天小编给大家分享的是常见的移动端前端适配方案分享,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。在网上搜了一下,很多面试都会被问到移动端适配方法的问题,最近看了一些文章,这里总结一下...
    99+
    2023-06-08
  • Android数据共享 sharedPreferences 的使用方法
    Android数据共享 sharedPreferences 的使用方法Android 中通过 sharedPreferences 来持久化存储数据并进行共享在 Activity 或存在 Context 环境中即可使用context.getS...
    99+
    2023-05-30
    android sharedpreferences roi
  • Java移除无效括号的方法实现
    目录一、题目二、示例三、解法1四、解法2一、题目 给你一个由 ‘('、')' 和小写字母组成的字符串 s。 你需要从字符串中删除最少数目的 ‘(' 或者 ‘)' (可以删除任意位置...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作