Android Handler消息处理顺序分析
看到Handler中的消息处理函数:
- public void dispatchMessage(Message msg){...}
这个函数是在Looper的执行消息循环loop()的时候取出Message然后执行:
- msg.target.dispatchMessage(msg);
时,msg对象的target就是这个Handler对象,即执行了Handler的dispatchMessage()函数:
函数定义如下:
- /**
- * Handle system messages here.
- */
- public void dispatchMessage(Message msg) {
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
从这个函数中可以看到,执行顺序逻辑是这样的:
1.如果Message对象有CallBack回调的话,就只执行这个回调,然后就结束了。
可见如果要使用Message的CallBack的话,就别在用其他的东西了。其实是个Runnable对象。
例如我们可以这样构建Message的CallBack:
- Message msgCallback = Message.obtain(myHandler, new Runnable() {
- @Override
- public void run() {
- Log.d(TAG, "msgCallback Runnable run() tid : " + Thread.currentThread().getId());
- }
- });
2.else分支下,如果Handler的CallBack对象不为空,那么就执行它的handleMessage()函数。
如果这个函数return true,那么就直接推出了,不会执行下面了。如果return false的话,就继续执行3.
例如我们可以这样来构建一个Handler的CallBack对象:
- private Handler.Callback callback = new Handler.Callback() {
- @Override
- public boolean handleMessage(Message msg) {
- Log.d(TAG, "Handler.Callback handleMessage msg : " + msg.what);
- Log.d(TAG, "Handler.Callback handleMessage tid : " + Thread.currentThread().getId());
- return false;
- // return true;
- }
- };
3.这才调用到了Handler的handleMessage()函数,也就是我们经常要在子类覆写的这个函数,从中我们可以做消息的处理。
附件中是我的测试Demo,也同时解惑了我的一个疑问,那就是Runnable对象到Handler中执行的时候,是不是另启动了新的线程呢?答案是否定的,这个Runnable对象只是被调用了它的run()方法,就像是一个普通的方法被调用了一样,根本就没有start一个线程,所以这个run()方法也是在Handler所在的线程中被执行的。
这个是handleCallback函数:
- private static void handleCallback(Message message) {
- message.callback.run();
- }
可以看到,只是调用了message对象的Runnable对象的run()函数。
当然,还得分析Handler的post(Runnable r)方法的Runnable对象最终是怎么被执行的,才能彻底解决我的疑问。
这个是Handler的post方法:
- public final boolean post(Runnable r)
- {
- );
- }
看到把Runnable对象r传到getPostMessage中了。
Handler中的getPostMessage方法:
- private static Message getPostMessage(Runnable r) {
- Message m = Message.obtain();
- m.callback = r;
- return m;
- }
可以看到,原来是这样啊。使用了Runnable对象r从Message中obtain()分配出一个Message对象出来,然后调用的是sendMessageDelayed来发送消息。
这就对了,我们自己post的Runnable对象,也不过是放到了Message的Runnable对象中了,也就是Message对象的CallBack了。他有优先执行的权利,事实上,我们如果通过post一个Runnable的话,也没办法修改更多的Message对象的参数信息了,所以只执行到这个Runnable也是合理的。
但是我却几乎没使用过Handler的callback对象,看来这个东西还是可以做优先级的消息过滤的,如果return true的话,就不去继续执行了。这个以后还是要研究研究具体怎么应用场景的啦。
Android Handler消息处理顺序分析的更多相关文章
- Android Handler 消息处理使用
本文内容 环境 演示 Handler 消息处理 参考资料 Handler 有两个主要作用或者说是步骤:发送消息和处理消息.在新启动的线程中发送消息,在主线程中获取.并处理消息.Android 平台只允 ...
- Android handler 内存泄露分析及解决方法
1. 什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引 ...
- 转 Android的消息处理机制(图+源码分析)——Looper,Handler,Message
作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种 ...
- 【转】android的消息处理机制(图+源码分析)——Looper,Handler,Message
原文地址:http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html#!comments 作为一个大三的预备程序员,我学习 ...
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种helper类,对于和我一样渴望水平得到进阶的人来说,都太值得一读了.这不,前几天为了了解android ...
- android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]
from:http://www.jb51.net/article/33514.htm 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.andro ...
- Android 消息处理源代码分析(1)
Android 消息处理源代码分析(1) 在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件 Handler.j ...
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类(转)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 最近创建了一个群,方便大家交流,群号: ...
- Android Handler 异步消息处理机制的妙用 创建强大的图片载入类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...
随机推荐
- log4net SmtpAppender 踩坑总结
错误集合: System.Net.Mail.SmtpException: 命令顺序不正确. 服务器响应为:Error: need EHLO and AUTH first ! System.Net.Ma ...
- MongoDB 创建数据库和查询数据
1.选择数据库 use test 2.创建用户 db.createUser({user:"test01",pwd:"12345",roles:[{role ...
- Hive数据库操作
Hive数据结构 除了基本数据类型(与java类似),hive支持三种集合类型 Hive集合类型数据 array.map.structs hive (default)> create table ...
- 了解这些后,再去决定要不要买Mac苹果电脑!
我清晰的记得,刚买的macbook pro回到家,开机后第一件事情,就是上了淘宝网,花了500元钱,找了一个上门维修电脑的师傅,上门给我装了一个windows系统......表砍我...当时买mac的 ...
- unity之龙骨动画
推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 我的个人博客 做游戏有史以来,第一次接触到龙骨动画,为新人引个路吧. (1)首先拿到美术给我三个文件,分别是name_ske. ...
- TortoiseSVN “*/SendRpt.exe not found”?
- vue---父调子 $refs (把父组件的数据传给子组件)
ps:App.vue 父组件 Hello.vue 子组件 App.vue : <template> <div id="app"> <input t ...
- k8s的高可用
一.高可用原理 配置一台新的master节点,然后在每台node节点上安装nginx,nginx通过内部的负载均衡将node节点上需要通过访问master,kube-apiserver组件的请求, ...
- SignalR 初体验
目录 一.前言 二.服务端 2.1.站点服务端 2.2.宿主服务或客户端 2.3.持久连接和集线器 三.客户端 3.1.使用代理客户端 3.2.不使用代理客户端 一.前言 微软官方给的说明:ASP.N ...
- PHP搭建大文件切割分块上传功能示例
转载:https://www.jb51.net/article/101931.htm 背景 在网站开发中,文件上传是很常见的一个功能.相信很多人都会遇到这种情况,想传一个文件上去,然后网页提示“该文件 ...