Android学习碎片(三)——Handler、Message、Runnable之间的联系①
2016-03-09 22:47
501 查看
个人对Android了解较为粗浅,如有谬误,敬请拍砖。
Handler类怎么发送消息到消息队列里暂且不管,今天先看Handler怎么处理消息。
Handler要处理消息首先会分发消息,即通过它的dispatchMessage(Message msg)方法,其源码如下:
先简单理一下这个方法包含的内容。
参数msg为被分发的Message对象。方法结构体是一个逻辑判断,首先判断msg的callback(属于Runnable类)为不为空值。如果不为空值,则执行handlerCallback(msg)方法,这个方法实际上就是执行callback的run方法。如果callback为空值,则接着判断Handler的mCallback(Handler的一个内部接口类)为不为空值,如果mCallback不为空值,则由它的handleMessage方法处理msg再根据其返回值决定是否由Handler的handleMessage方法继续处理msg,如果mCallback为空值,则直接由Handler处理msg。
根据dispatchMessage的消息处理流程可以分几种情况简单应用。
当我们只需要开启一个子线程,处理一下UI事件的时候,我们可以直接使用Handler类的post(Runnable r)方法,其源码如下:
这个方法实际上是使用sendMessageDelayed方法发送消息,只不过延迟时间为0。再看一下getPostMessage(r)的源码:
同样是依靠callback处理消息,还可以用另外一种方式来实现,即直接实例一个Message对象,再初始化其callback对象。而初始化其callback对象,必须通过Message的静态方法obtain(Handler h, Runnable callback)初始化才行,其源码如下:
想要获得Message的target和callback可以通过getTarge方法和getCallback方法。
当需要根据 不同的消息来处理事件的时候,Runnable就不好用了,我们需要实现Handle的成员接口类Callback或者继承Handler来处理。
前面讲了,当Handler的mCallback对象不为空时,需要根据mCallback接口的handleMessage方法的返回值来决定是否继续由Handler处理消息。mCallback的是Callback类,源码如下:
所以只有当各种条件都满足的时候,才会由Handler的handleMessage来处理Message。它的源码如下:
所以当我们需要用Handler的handleMessage来处理消息的时候,我们必须继承Handler类重写这个方法。
关于Handler、Meesage、Runnable之间的联系先就写这么多,下次有空接着学习。
Handler类怎么发送消息到消息队列里暂且不管,今天先看Handler怎么处理消息。
Handler要处理消息首先会分发消息,即通过它的dispatchMessage(Message msg)方法,其源码如下:
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
先简单理一下这个方法包含的内容。
参数msg为被分发的Message对象。方法结构体是一个逻辑判断,首先判断msg的callback(属于Runnable类)为不为空值。如果不为空值,则执行handlerCallback(msg)方法,这个方法实际上就是执行callback的run方法。如果callback为空值,则接着判断Handler的mCallback(Handler的一个内部接口类)为不为空值,如果mCallback不为空值,则由它的handleMessage方法处理msg再根据其返回值决定是否由Handler的handleMessage方法继续处理msg,如果mCallback为空值,则直接由Handler处理msg。
根据dispatchMessage的消息处理流程可以分几种情况简单应用。
当我们只需要开启一个子线程,处理一下UI事件的时候,我们可以直接使用Handler类的post(Runnable r)方法,其源码如下:
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
这个方法实际上是使用sendMessageDelayed方法发送消息,只不过延迟时间为0。再看一下getPostMessage(r)的源码:
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }实际上就是实例化了一个Message对象,再初始化了callback对象而已。当Handler分发消息,即执行dispatchMessage方法的时候,由于msg的callback不为空值则会执行handleCallback方法,handleCallback的源码如下:
private static void handleCallback(Message message) { message.callback.run(); }一目了然,这个方法最终还是执行的是callback的run方法。
同样是依靠callback处理消息,还可以用另外一种方式来实现,即直接实例一个Message对象,再初始化其callback对象。而初始化其callback对象,必须通过Message的静态方法obtain(Handler h, Runnable callback)初始化才行,其源码如下:
public static Message obtain(Handler h, Runnable callback) { Message m = obtain(); m.target = h; m.callback = callback; return m; }在这个方法里初始化了一个Message对象,然后为它初始化了target和callback,target就是Handler对象。初始化完后接着发送消息,这里不需要重新new一个Handler对象,只需要使用Message的sendToTarget方法就行了,sendToTarget的源码如下:
public void sendToTarget() { target.sendMessage(this); }就是使用刚才初始化的target发送消息。
想要获得Message的target和callback可以通过getTarge方法和getCallback方法。
当需要根据 不同的消息来处理事件的时候,Runnable就不好用了,我们需要实现Handle的成员接口类Callback或者继承Handler来处理。
前面讲了,当Handler的mCallback对象不为空时,需要根据mCallback接口的handleMessage方法的返回值来决定是否继续由Handler处理消息。mCallback的是Callback类,源码如下:
public interface Callback { public boolean handleMessage(Message msg); }它是个接口类,需要我们自己实现它的方法,我们自己决定handleMessage的返回值。当我们决定返回true的时候,就只有Callback处理消息;当我们决定返回false的时候,消息还会由Handler继续处理。
所以只有当各种条件都满足的时候,才会由Handler的handleMessage来处理Message。它的源码如下:
public void handleMessage(Message msg) { }不要怀疑你的眼睛,源码就是这样,这个方法什么都没做。
所以当我们需要用Handler的handleMessage来处理消息的时候,我们必须继承Handler类重写这个方法。
关于Handler、Meesage、Runnable之间的联系先就写这么多,下次有空接着学习。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories