说到Handler,今天遇到一个问题:就是handler 发送了消息,却在handleMessage的地方没有收到消息,甚是奇怪。代码如下:
-
- HandlerThread handlerThread = new HandlerThread("handler_thread");
- handlerThread.start();
-
- mHandler = new Handler(handlerThread.getLooper());
以上代码,是多么正常的实例化mHandler;然后通过 mHandler.sendEmptyMessage(0); 发送一个消息出去,这是又多么简单的一次操作。可结果却是多么的出人意料。因为同样的代码,同样的操作,可程序在某些情况下,却收不到了消息?!无奈,只能去分析下源码,看看为什么没有收到消息?!
问题根因跟踪分析:
1、当我们调用 sendEmptyMessage()方法的时候,最终会调用到 Handler.enqueueMessage 方法
- private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
- msg.target = this;
- if (mAsynchronous) {
- msg.setAsynchronous(true);
- }
- return queue.enqueueMessage(msg, uptimeMillis);
- }
2、然后跟踪到 MessageQueue.enqueueMessage方法。
- final boolean enqueueMessage(Message msg, long when) {
- ........
- boolean needWake;
- synchronized (this) {
-
- if (mQuiting) {
- RuntimeException e = new RuntimeException(
- msg.target + " sending message to a Handler on a dead thread");
- Log.w("MessageQueue", e.getMessage(), e);
- return false;
- }
-
- ................
- }
- }
- if (needWake) {
- nativeWake(mPtr);
- }
- return true;
- }
3、那么mQuitting 什么情况会赋值 true呢?跟踪代码找到如下代码:
- final void quit() {
- if (!mQuitAllowed) {
- throw new RuntimeException("Main thread not allowed to quit.");
- }
-
- synchronized (this) {
- if (mQuiting) {
- return;
- }
- mQuiting = true;
- }
- nativeWake(mPtr);
- }
由此可见,当调用 quit的时候会对mQuiting进行赋值true,这样在以后的发送消息的时候,就不会添加到消息队列当中去了。
而官方的sendEmptyMessage定义也证明了这一点。
-
-
-
-
-
-
-
-
- public final boolean sendEmptyMessage(int what)
- {
- return sendEmptyMessageDelayed(what, 0);
总结:
通过上面分析,问题的原因就有可能是不合法的调用了 quit方法,搜索项目,发现有些地方,在某些情况下会不和业务逻辑的去执行 quit方法,导致无法处理的消息。再就是可能的一个原因,就是 HandlerThread可能会系统强制回收了。
所以,为了安全,我们在调用 发送消息的时候最好做一个判断,如果消息发送不成功则重新创建handler。代码如下:
- private void createHandler(){
- HandlerThread handlerThread = new HandlerThread("handler_thread");
- handlerThread.start();
- mHandler = new Handler(handlerThread.getLooper());
- }
-
- private void sendMessage(int what){
- boolean isOk = mHandler.sendEmptyMessage(what);
- if (!isOk){
-
- createHandler();
- isOk = mHandler.sendEmptyMessage(what);
- }
- }
原文地址:http://blog.csdn.net/ilygjl/article/details/51137346