[原创]Android Handler使用Message的一个注意事项
最近发现了一个莫名其妙的问题,在使用Handler.post(Runnable)这个接口时,Runnable有时候没有运行,非常奇怪,后来发现是因为调用Handler.removeMessage()时,what参数传的0,导致Runnable所在的Message被remove了,下面看下源码。
class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DO_SOME:
Log.i("zhoukewen", "what ==== 0........");
break;
}
}
} Handler h = new MyHandler(); final int MSG_DO_SOME = 0; public void onStartClick(View view) { h.sendEmptyMessage(MSG_DO_SOME);
h.post(new Runnable() {
@Override
public void run() {
Log.i("zhoukewen", "runnable............");
}
});
h.removeMessages(MSG_DO_SOME);
}
情景大概如图所示,开发者也许希望删除what=MSG_DO_SOME的msg,但当SG_DO_SOME恰好等于0时,会连带携带Runnable的msg也被删除,我们看下post源码:
先看Handler.java
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
} private final Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
再看Message.obtain()
public int what; public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}
可以看到,post(Runnable)时实际上也是创建一个Message,从代码中看到,该Message要不就是从sPool池中获取,要不就是new出来的,如果new出来的,其成员变量自然被初始化为0。如果从sPool中获取的话,sPool中的Message都是经过recycle()之后才能使用的,我们看源码:
public void recycle() {
clearForRecycle(); synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
} /*package*/ void clearForRecycle() {
flags = 0;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
replyTo = null;
when = 0;
target = null;
callback = null;
data = null;
}
果然也是设置为0。所以,Handler.post(Runnable)其实就是生成一个what为0的Message,而当remove时,会删除所有what为0的Message,也就是吧Runnable的Message删除了,所以导致了之前看到的诡异问题。
[原创]Android Handler使用Message的一个注意事项的更多相关文章
- 转载《Android Handler、Message》
之前也是由于周末通宵看TI3比赛,一直没找到时间写博客,导致已经有好久没更新了.惭愧!后面还会恢复进度,尽量保证每周都写吧.这里也是先恭喜一下来自瑞典的Alliance战队夺得了TI3的冠军,希望明年 ...
- Android Handler、Message完全解析,带你从源码的角度彻底理解
之前也是由于周末通宵看TI3比赛,一直没找到时间写博客,导致已经有好久没更新了.惭愧!后面还会恢复进度,尽量保证每周都写吧.这里也是先恭喜一下来自瑞典的Alliance战队夺得了TI3的冠军,希望明年 ...
- Android handler真的是重新启动一个线程吗?
我们说handler是开启了另外一个线程,而且看代码的话确实是这样,实现了runnable接口,这在java中就是开启了一个线程,但是情况中的是这样吗?我们不妨来做个试验,如下 import andr ...
- Android Handler之Message传递参数
最近发现Message,发送消息可以传递参数,这个思路很好,所以写了一个例子,点击屏幕,给Activity发送一个消息,传递两个参数,并把这个activity销毁掉! 程序打开界面: 点击屏幕,销毁a ...
- Android Handler、Message、MessageQueue和Looper官方说明
Handler官方说明 官方API文档:https://developer.android.google.cn/reference/android/os/Handler Handler允许您发送和处理 ...
- android handler ,message消息发送方式
1.Message msg = Message.obtain(mainHandler) msg.obj=obj;//添加你需要附加上去的内容 msg.what = what;//what消息处理的类 ...
- 与多线程结合使用的消息处理类Handler、Message
1. 消息处理类——Handler 消息处理类(Handler)允许发送和处理Message或Runnable对象到其所在线程的MessageQueue中.Handerl有以下两个主要作用: 将Mes ...
- Android 异步消息处理机制 让你在深入了解 Looper、Handler、Message之间的关系
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 非常多人面试肯定都被问到过,请问And ...
- Android之消息机制Handler,Looper,Message解析
PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...
随机推荐
- 高手速成android开源项目【导航篇】
Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧和创造力.学习开源代码是掌握技术的一个 ...
- 在Android中开源类库使用过程中兼容性等问题的讨论
1.在Android4.0环境下编译的actionbarsherlock.slidingmenu类库,能不能在4.0以下的版本中使用 相信很多人跟我一样,都以为在低版本(如Android2.1或2.3 ...
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)
上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...
- [ACM_水题] ZOJ 3706 [Break Standard Weight 砝码拆分,可称质量种类,暴力]
The balance was the first mass measuring instrument invented. In its traditional form, it consists o ...
- Windows 8.1 开发过程中遇到的小问题
最近在开发Windows 8 应用的时候碰到了一个莫名的问题,错误内容如下:(其中 **.DLL是本地创建的项目,在主项目中添加了引用,其中大部分代码是MVVM light 框架库的代码) Syste ...
- JPA oneToMany 级联更新
oneToMany 使用: 示例:Employee与Phone为例. 1.类定义如下: package com.vrvwh.wh01.domain; import javax.persistence. ...
- Nodejs学习笔记(十一)--- 数据采集器示例(request和cheerio)
目录 写在之前 示例 示例要求 采集器 加入代理 请求https 写在之后... 写在之前 很多人都有做数据采集的需求,用不同的语言,不同的方式都能实现,我以前也用C#写过,主要还是发送各类请求和正则 ...
- C语言实现单链表-03版
在C语言实现单链表-02版中我们只是简单的更新一下链表的组织方式: 它没有更多的更新功能,因此我们这个版本将要完成如下功能: Problem 1,搜索相关节点: 2,前插节点: 3,后追加节点: 4, ...
- Leetcode 278 First Bad Version 二分查找(二分下标)
题意:找到第一个出问题的版本 二分查找,注意 mid = l + (r - l + 1) / 2;因为整数会溢出 // Forward declaration of isBadVersion API. ...
- Spring 之autowired
Spring中autowired主要用于装配树形值,其关键类为BeanWrapperImpl,阅读代码发现其关键方法setPropertyValue有如下一段代码. PropertyHandler p ...