博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原创]Android Handler使用Message的一个注意事项
阅读量:5825 次
发布时间:2019-06-18

本文共 2308 字,大约阅读时间需要 7 分钟。

最近发现了一个莫名其妙的问题,在使用Handler.post(Runnable)这个接口时,Runnable有时候没有运行,非常奇怪,后来发现是因为调用Handler.removeMessage()时,what参数传的0,导致Runnable所在的Message被remove了,下面看下源码。

1     class MyHandler extends Handler { 2         @Override 3         public void handleMessage(Message msg) { 4             switch (msg.what) { 5                 case MSG_DO_SOME: 6                     Log.i("zhoukewen", "what ==== 0........"); 7                     break; 8             } 9         }10     }11 12     Handler h = new MyHandler();13 14     final int MSG_DO_SOME = 0;15 16     public void onStartClick(View view) {17 18         h.sendEmptyMessage(MSG_DO_SOME);19         h.post(new Runnable() {20             @Override21             public void run() {22                 Log.i("zhoukewen", "runnable............");23             }24         });25         h.removeMessages(MSG_DO_SOME);26     }

情景大概如图所示,开发者也许希望删除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删除了,所以导致了之前看到的诡异问题。

 

转载地址:http://gmidx.baihongyu.com/

你可能感兴趣的文章
运维工程师在干什么学些什么?【致菜鸟】
查看>>
Linux中iptables详解
查看>>
java中回调函数以及关于包装类的Demo
查看>>
***常用兵器之扫描篇(下)
查看>>
maven异常:missing artifact jdk.tools:jar:1.6
查看>>
终端安全求生指南(五)-——日志管理
查看>>
Nginx 使用 openssl 的自签名证书
查看>>
创业维艰、守成不易
查看>>
PHP环境安装套件:快速安装LAMP环境
查看>>
CSS3
查看>>
ul下的li浮动,如何是ul有li的高度
查看>>
C++ primer plus
查看>>
python mysqlDB
查看>>
UVALive 3942 Remember the Word Tire+DP
查看>>
Android之HttpClient
查看>>
从微软的DBML文件中我们能学到什么(它告诉了我们什么是微软的重中之重)~目录...
查看>>
被需求搞的一塌糊涂,怎么办?
查看>>
centos 7.2编译安装nginx-1.12.0
查看>>
c_数据结构_队的实现
查看>>
jquery 选择器总结
查看>>