Handler中的handleMessage方法不执行的原因
记录开发过程中发生Handler中的handleMessage不执行的原因:
Handler源码位置/frameworks/base/core/java/android/os/Handler.java
纵观Handler整类的源码可以发现会涉及到Handler的handleMessage执行的方法一个是dispatchMessage,还有一个就是removeMessages。先来看dispatchMessage方法。
从Handler的dispatchMessage源码可以发现如果在msg中添加了CallBack或者在创建Handler的时候设置了CallBack都会导致Handler的handleMessage方法不执行的问题,下面详细解释一下。
public void dispatchMessage(Message msg) {
98 if (msg.callback != null) {
99 handleCallback(msg);
100 } else {
101 if (mCallback != null) {
102 if (mCallback.handleMessage(msg)) {
103 return;
104 }
105 }
106 handleMessage(msg);
107 }
108 }
从上面的代码可以看出
- 创建msg的时候给msg添加了CallBack回调,Handler在执行dispatch方法进行消息分发的时候会先去判断msg是否设置了CallBack如果设置了CallBack就会执行msg自带的CallBack回调而不会执行Handler的handleMessage方法。
- 创建Handler的时候给Handler设置了CallBack,那么在Handler进行消息分发的时候发现msg没有CallBack但是Handler本身有CallBack并且Handler的CallBack的handleMessage方法返回的是true的话那么Handler的handleMessage方法也不会执行。
接下来看一下removeMessages方法为什么会影响到Handler的handleMessage执行。
public final void removeMessages(int what) {
753 mQueue.removeMessages(this, what, null);
754 }
755
756 /**
757 * Remove any pending posts of messages with code 'what' and whose obj is
758 * 'object' that are in the message queue. If <var>object</var> is null,
759 * all messages will be removed.
760 */
761 public final void removeMessages(int what, Object object) {
762 mQueue.removeMessages(this, what, object);
763 }
764
从上面的源码可以看出调用了Handler的removeMessages方法,会去调用mQueue的removeMessages方法,mQueue的removeMessages方法则会将消息队列中的message移除这样的话消息已经不存在消息队列中所以这个消息也不会被执行,那么对应的Handler的handleMessage方法也不会执行。 以上就是通过代码分析出来可能导致Handler的handleMessage不执行的情况。
实际上在项目中还会有其他问题,比如looper获取不到系统的时间片、handler的handleMessage执行的方法存在死锁不能退出、Handler的Looper所在的线程出现Crash等,因此在实际项目开发过程中一定要保证handler的handleMessage方法不要执行会存在死锁的方法,并且一定要保证合理使用cpu,同时需要注意不要在Handler的Looper所在的线程中如果出现Crash一定要有明确的日志进行定位。