Android Handler消息处理顺序分析

200 篇文章 0 订阅
91 篇文章 0 订阅


看到Handler中的消息处理函数:

Java代码   收藏代码
  1. public void dispatchMessage(Message msg){...}  

这个函数是在Looper的执行消息循环loop()的时候取出Message然后执行:

 

 

Java代码   收藏代码
  1. msg.target.dispatchMessage(msg);  

 时,msg对象的target就是这个Handler对象,即执行了Handler的dispatchMessage()函数:

 

函数定义如下:

 

 

 

Java代码   收藏代码
  1. /** 
  2.  * Handle system messages here. 
  3.  */  
  4. public void dispatchMessage(Message msg) {  
  5.     if (msg.callback != null) {  
  6.         handleCallback(msg);  
  7.     } else {  
  8.         if (mCallback != null) {  
  9.             if (mCallback.handleMessage(msg)) {  
  10.                 return;  
  11.             }  
  12.         }  
  13.         handleMessage(msg);  
  14.     }  
  15. }  

 

从这个函数中可以看到,执行顺序逻辑是这样的:

 

1.如果Message对象有CallBack回调的话,就只执行这个回调,然后就结束了。

可见如果要使用Message的CallBack的话,就别在用其他的东西了。其实是个Runnable对象。

 

例如我们可以这样构建Message的CallBack:

Java代码   收藏代码
  1. Message msgCallback = Message.obtain(myHandler, new Runnable() {  
  2.      
  3.     @Override  
  4.     public void run() {  
  5.           
  6.         Log.d(TAG, "msgCallback Runnable run() tid : " + Thread.currentThread().getId());  
  7.           
  8.     }  
  9. });  

 

 

2.else分支下,如果Handler的CallBack对象不为空,那么就执行它的handleMessage()函数。

如果这个函数return true,那么就直接推出了,不会执行下面了。如果return false的话,就继续执行3.

 

   例如我们可以这样来构建一个Handler的CallBack对象:

Java代码   收藏代码
  1.     private Handler.Callback callback = new Handler.Callback() {  
  2.         @Override  
  3.         public boolean handleMessage(Message msg) {  
  4.               
  5.             Log.d(TAG, "Handler.Callback handleMessage msg : " + msg.what);  
  6.             Log.d(TAG, "Handler.Callback handleMessage tid : " + Thread.currentThread().getId());  
  7.               
  8.             return false;  
  9. //            return true;  
  10.         }  
  11.     };  

 

 

3.这才调用到了Handler的handleMessage()函数,也就是我们经常要在子类覆写的这个函数,从中我们可以做消息的处理。

 

附件中是我的测试Demo,也同时解惑了我的一个疑问,那就是Runnable对象到Handler中执行的时候,是不是另启动了新的线程呢?答案是否定的,这个Runnable对象只是被调用了它的run()方法,就像是一个普通的方法被调用了一样,根本就没有start一个线程,所以这个run()方法也是在Handler所在的线程中被执行的。

 

这个是handleCallback函数:

Java代码   收藏代码
  1. private static void handleCallback(Message message) {  
  2.     message.callback.run();  
  3. }  

 可以看到,只是调用了message对象的Runnable对象的run()函数。

 

当然,还得分析Handler的post(Runnable r)方法的Runnable对象最终是怎么被执行的,才能彻底解决我的疑问。

 

这个是Handler的post方法:

Java代码   收藏代码
  1. public final boolean post(Runnable r)  
  2. {  
  3.    return  sendMessageDelayed(getPostMessage(r), 0);  
  4. }  

 看到把Runnable对象r传到getPostMessage中了。

 

Handler中的getPostMessage方法:

Java代码   收藏代码
  1. private static Message getPostMessage(Runnable r) {  
  2.     Message m = Message.obtain();  
  3.     m.callback = r;  
  4.     return m;  
  5. }  

 可以看到,原来是这样啊。使用了Runnable对象r从Message中obtain()分配出一个Message对象出来,然后调用的是sendMessageDelayed来发送消息。

 

       这就对了,我们自己post的Runnable对象,也不过是放到了Message的Runnable对象中了,也就是Message对象的CallBack了。他有优先执行的权利,事实上,我们如果通过post一个Runnable的话,也没办法修改更多的Message对象的参数信息了,所以只执行到这个Runnable也是合理的。

 

       但是我却几乎没使用过Handler的callback对象,看来这个东西还是可以做优先级的消息过滤的,如果return true的话,就不去继续执行了。这个以后还是要研究研究具体怎么应用场景的啦。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值