https://www.jianshu.com/p/737646300fce

在阅读老人的源码中,发现以下代码片段

private handleMessage(Message msg) {    switch(msg.what) {        case ACTION_XXX:            // do something...            this.removeMessages(ACTION_XXX);            break;            //other cases        }} 

1. 猜想

初步猜测其作用是为了处理某消息后,清除在消息队列中等待的同类消息,以达到防止在处理过程中重复发送的目的

2. 验证

于是写一个demo验证之(因为上述源码触发效果过为复杂,所以不用此进行验证)

mHandler.setHandlerCallBack(new MyHandler.MyHandlerCallBack() {    @Override    public void handleMessage(Message message) {        Log.i(TAG, "handleMessage: " + message.arg1);        if (message.what == ACTION_ODD) {            mMyHandler.removeMessages(ACTION_ODD);        }    }});mButton.setOnClickListener(new View.OnClickListener() {    @Override    public void onClick(View v) {        Message message = Message.obtain();        message.what = number % 2 == 0 ? ACTION_EVEN : ACTION_ODD;        message.arg1 = number;                // 将handleMessage延迟1s调用        mHandler.sendMessageDelayed(message, 1000);        number++;    }});

快速点击Button后,观察log日志输出

02-16 10:51:08.787 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 002-16 10:51:08.958 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 102-16 10:51:09.112 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 202-16 10:51:09.489 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 402-16 10:51:09.762 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 602-16 10:51:10.100 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 802-16 10:51:10.237 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 9

3. 推论

从日志输出可以得知偶数全部被输出,而1~9中的奇数被过滤了
可以推断handleMessage在输出Message.what==1的log结束后,调用Handler.removeMessages将Message.what为ACTION_ODD从消息队列中移除,所以中间的消息被过滤掉了。

4. 查看源码

查看源码是最好的验证方式,所以先查看Handler的removeMessages方法源码

// Handler.javapublic final void removeMessages(int what) {    mQueue.removeMessages(this, what, null);}

可以看出,这里实际上是移除消息队列的message,再看看MessageQueue中的removeMessages方法源码

// MessageQueue.javavoid removeMessages(Handler h, int what, Object object) {    if (h == null) {        return;    }    synchronized (this) {         Message p = mMessages;        // 原代码注释,Remove all messages at front.        // 根据上面传入的参数,p!=null成立,p.target == h成立,object == null 成立        // 即此处可等同为p.what == what        // 此处代码即找到第一个p.what == what的消息并将其移除        while (p != null && p.target == h && p.what == what               && (object == null || p.obj == object)) {            Message n = p.next;            mMessages = n;            p.recycleUnchecked();            p = n;        }        // Remove all messages after front.        // 此处即为移除找到第一个后的Message        while (p != null) {            Message n = p.next;            if (n != null) {                // 同上,此处也可以等同为p.what == what                if (n.target == h && n.what == what                    && (object == null || n.obj == object)) {                    Message nn = n.next;                    n.recycleUnchecked();                    p.next = nn;                    continue;                }            }            p = n;        }    }}

由源码中可以看出,MessageQueue将Message.what与函数传入的what相同的Message从队列中移除,和推论相符


这是本人第一次进行探讨,如有什么错误,请在评论区进行纠正。



作者:呆呆李宇杰
链接:https://www.jianshu.com/p/737646300fce
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

更多相关文章

  1. Android消息机制——时钟显示和异步处理工具类(AsyncTask)
  2. Android(安卓)studio 打包aar
  3. android 2.2(froyo)源码下载
  4. EventBus源码解析(基于Android(安卓)O)
  5. Android:Handler中的Idle Handler
  6. Android开发推荐资料大合集 【转载自51CTO】
  7. 资源连接

随机推荐

  1. android 9.0系统重启的代码详解
  2. Android内核源码阅读---ashmem.c
  3. Android的一些常用命令提示符(cmd)指令
  4. Android中使用SAX方式解析XML文件
  5. React Native Android环境配置 第一个实
  6. Android(安卓)子fragment中获取父fragmen
  7. 【Mark】Android TextView属性详解
  8. Android中为按钮设置点击音效
  9. Android消息处理系统原理简要概述
  10. Google Android操作系统内核编译图文教程