Handler机制在Android多线程编程中可以说是不可或缺的角色,也是必须掌握的内容,所以深入掌握并应用Handler异步处理机制在Android开发中显得特别重要。它在使用的过程中主要与Messgae、MessageQueue、和Looper这三个对象关联密切,Handler机制的实现原理依赖于这三者
在Android中Handler常用于在子线程发送结果,然后通知在主线程中刷新视图界面。
Message为消息的载体,这个类实现了Parcelable借口,Message中含有what,arg1,arg2,obj,target等成员变量,what常用来作为一个标志,消息数据则是放在obj中,Message.obtain()方法生成一个Message对象。
Looper是线程用来运行消息循环(message loop)的类。常用的方法为Looper.prepare()和Looper.loop()。Looper.prepare()用于生成一个Looper对象,Looper.loop()用于无限循环分发MessageQueue中的消息。主线程中Looper是应用启动时候系统主动的创建的。子线程可以通过Looper.prepare()来创建,一个线程中只能存在一个Looper。
MessageQueue是一个消息队列,通过单链路数据结构来实现的,用于存储消息的集合。主要方法有:enqueueMessage(Messagemsg, long when),插入消息,next(),取出消息,quit(),关闭。其中next()是个阻塞方法,里面是一个无限for不断的取消息,如果存在消息便取出,否则便阻塞,主线程便会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生时,才通过往pipe管道写端写入数据来唤醒主线程工作。主线程中MessageQueue是创建Looper的时候创建的,所以使用主线程中的Handler时候,不需要自己去创建。
Handler
1.Handler() 默认构造方法,与当前线程及其Looper实例绑定。如在主线程中执行new Handler(),那么该handler实例所绑定的便是 UI 线程和 UI 线程绑定的Looper实。
2.Handler(Callback callback)自定义一个回调方法。
3.Handler(Looper looper)自己传入一个Looper对象。
不过所有的构造方法最后都会调用Handler(Looper looper, Callback callback, boolean async);
Handler中常用的方法:
^post(Runnable):将runnable对象入队。
^postAtTime(Runnable, long):将runnable对象入队,并在指定时间执行
^postDelayed(Runnable, long):将runnable对象入队,并经过指定时间后执行。
^sendEmptyMessage(int):发送只具有what标志值得message。
^sendMessage(Message):将一个message对象入队,且允许该message对象带有一些数据,如一个bundle类型的数据或一个int类型的标志值等,这些数据将在Handler的handleMessage(Message) 方法中进行处理,当然,具体处理逻辑需要我们自己重写handleMessage()方法。
^sendMessageDelayed(Message, long):将message入队,并在当前时间延迟指定时间长度前将该消息放在所有挂起的消息之后。
^sendMessageAtTime(Message, long):将message入队,并在指定时间到之前将该消息放在所有挂起的消息之后。
以上便是比较常用的方法,并且可以看出上面的所有方法最终调用的都是sendMessageAtTime(Message, long) 这个方法(如果传入的参数是runnable的话,会先调用getPostMessage(Runnable) 或getPostMessage(Runnable, Object)方法获取消息),然后由sendMessageAtTime(Message, long) 为message对象指定target为该handler实例,并返回一个enqueueMessage(MessageQueue, Message, long) 方法,该方法如下,最终通过MessageQueue的enqueueMessage(Message, long) 将消息成功送进消息队列中。
使用流程的话:一般先创建一个Handler,然后在子线程工作完成后,通过Message打包数据,使用handler对象发送,最后在Handler中处理子线程发送过来的结果。一个线程中只能存在一个Looper和MessageQueue,但可以存在多个Handler,Handler可以跨线程使用。