看到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) { return sendMessageDelayed(getPostMessage(r), 0); }
看到把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应用开发工程师而言,本书中关于Binder,以及sp、wp、Handler和Looper等常用类的分析或许能帮助你迅速适应Android平台上的开发工作。 (2)Android系统开发工程师 Android系统开发工程师常常需要...
本网盘分享章节编号是按照视频更新的先后顺序编号的,具体学习可参考如下章节顺序: 【第一版第一章】老罗Android开发视频--入门介绍(9集) 【第一版第二章】老罗Android开发视频--常用UI布局介绍(5集) 【第一...
基于Handler的Android计时器与倒计时器 原始地址: 特性 支持操作: 开始 暂停 恢复 取消 使用 allprojects { repositories { .. . maven { url ' https://jitpack.io ' } } } dependencies { .. . compile...
Andriod提供了Handler和Looper来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(Message Exchange). 1)Looper:一个线程可以产生一个Looper对象,由它来管理此线程里的Message ...
保持消息的顺序。 消息持久化是使用 SqliteDb 处理的。 它克服了 PAHO 库中的一些限制(在下一节中提到) 检查连接并自动重新连接。 所有操作都发生在后台(MQTT_Thread)线程上。 支持 SSL。 事情怎么样 ...
GSMCallTracker在本质上是一个Handler。 GSMCallTracker是Android的通话管理层。GSMCallTracker建立了ConnectionList来管理现行的通话连接,并向上层提供电话调用接口。 在 GSMCallTracker中维护着通话列表:...
通过使用处理程序,可运行程序和服务按时间顺序发送SMS
3.新增了顺序播放、随机播放和单曲循环3种播放模式 4.新增了上一首和下一首歌曲切换功能,并且自动播放下一首 5.新增了读取模拟器SD卡的音乐文件,操作简单方便 6.新增了JSON格式文件的解析,显示歌手详细信息 7....
AsyncTask类一般是android开发人员接触的最早的异步处理方法,虽然现在流行的有很多新的异步任务类,如RxJava等,但是对于AsyncTask的底层实现原理还是有必要了解学习的,对于我们自己理解其他框架或者自己设计框架...
我的理解:子任务程协作运行,优雅的处理异步问题解决方案。 它能干什么? 我在做安卓开发,它能替换掉Handler,AsyncTask 甚至是Rxjava来优雅的解决异步问题。 下面让我们从基础开始吧,假设有一个名为launch可以
1、打开AP6212的BT,关闭rtl8723bs的BT(其它都是按照比对软件的字母顺序了): [ 3.141273] Bluetooth: HCI UART driver ver 2.2 [ 3.146210] Bluetooth: HCI H4 protocol initialized [ 3.151563] Bluetooth: HCI ...
缓存购物车写法 写入txt到缓存bannerview:防止OOM写法的bannerviewbannerviewquan:市面大部分bannerview写法baseactivitys:加了堆栈管理和678android权限的base类cacheutil:清除缓存方法caranimation:购物车...