Handler消息传递机制
2015-12-15 15:37
302 查看
Handler消息传递机制
出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,则可能导致线程安全问题。为了解决这个问题,Android制定了一条简单的规定:只允许UI线程(主线程)修改Activity里的UI组件。稍微想一想,如果新启动的线程需要动态修改界面组件怎么办呢。这时候就需要借助于Handler的消息机制来实现了。
Handler类简介
为了解决新线程动态修改界面组件的问题,所以引入了Handler类。所以Handler类主要作用有两个:在新启动的线程中
发送消息
在主线程中
获取、处理消息
我们只需重写Handler类中处理消息的方法。当新启动的线程发送消息的时候,该消息就会放到与它相关的MessageQueue(不难想到,一个新线程只需要有一个MessageQueue)。Handler会不断从MessageQueue中获取并处理消息,这样就会让我们重写的方法被回调了。
Handler类包含如下的方法用于发送、处理消息:
void handleMessage(Message msg)处理消息的方法。该方法通常用来重写
final boolean hasMessages(int what)检查消息队列中是否包含what属性为指定值的消息
final boolean hasMessages(int what , Object object)检查消息队列中是否包含what属性为指定值且object属性为指定对象的消息
Message obtainMessage()获取消息
sendEmptyMessage(int what)发送空消息
final boolean sendEmptyMessageDelayed(int what ,long delayMillis)多少毫秒之后发送空消息
final boolean sendMessage(Message msg)立即发送消息
finla boolean sendMessageDelayed(Message msg , long delayMillis)多少毫秒之后发送消息
Handler获取,处理消息
上面提到Handler是得到消息,然后处理消息的一个类,而MessageQueue是一个消息队列。那么是不是还差一个把消息放入MessageQueue中和把消息拿出来交给Handler处理的一个类呢。所以引入了一个Looper类:Looper的主要功能:
Looper负责管理MessageQueue,会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理。获得一个Looper对象
上面提到每个线程最多只需要一个MessageQueue,所以一个线程中最多只能有一个Looper对象。看一下Looper构造器源码:private Looper(){ mQueue = new MessageQueue(); mRun = true; mThread = mThread.currentThread(); }
可以看到构造器是使用private修饰的,所以程序员不能通过new来创建一个Looper对象。所以Looper类提供了一个
prepare()方法来创建一个Looper对象。
prepare()方法的源码:
private static final void prepare(){ if(sThreadLocal.get() != null) throw new RuntimeException("Only one Looper may be created per thread"); sThreadLocal.set(new Looper()); }
从上面的源码可以看出,
prepare()对象保证了每个线程最多只有一个Looper对象。
通过Looper对象分发消息给Handler
当获得一个Looper对象之后,我们现在应该做的就是通过Looper对象,向MessageQueue中取出消息然后分发给Handler。Looper提供了静态的loop()方法。
loop()方法使用一个死循环不断取出MessageQueue中的消息,并将取出的消息分给该消息对应的Handle进行处理。
总结
Looper、MessageQueue、Handler各自的作用:
Looper : 每个线程只有一个Looper,它负责管理MessageQueue,会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理MessageQueue : 由Looper负责管理。
Handler : 他能把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息。
新线程中使用Handler的步骤
调用Looper的perpare()方法为当前创建Looper对象,创建Looper对象时,他的构造器会创建与之配套的MessageQueue。
有了Looper之后,创建Handler子类的实例,重写
handleMessage()方法,该方法负责处理来自其他线程的消息。
调用Looper的
loop()方法启动Looper。
相关文章推荐
- 使用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