关于Handler.removemessages方法
16lz
2021-01-24
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
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
更多相关文章
- Android消息机制——时钟显示和异步处理工具类(AsyncTask)
- Android(安卓)studio 打包aar
- android 2.2(froyo)源码下载
- EventBus源码解析(基于Android(安卓)O)
- Android:Handler中的Idle Handler
- Android开发推荐资料大合集 【转载自51CTO】
- 资源连接