android之handler总结及Handler关键源码分析
什么是Handler
官方文档中的说法是:一个Handler允许你发送或处理一个Message或Runnable对象。每个Handler实例都和一个单独的线程及此线程的消息队列关联。当你创建一个新的handler对象时它会绑定到那个创建它的线程及此线程的消息对列上。从这一点上来说,Handler会传递messages和runnables到与它关联的消息对列上,当它们出队时执行它们。
文档中说Handler可以用来发送Message或Runnable,其实发送的都是Message,我们可以查看Handler的源码,找到PostXXX()方法,可以发现这此方法最终都会调用 sendMessageAtTime(getPostMessage(r), uptimeMillis);而其中的getPostMessage(r)方法的定义如下:
1 private static Message getPostMessage(Runnable r) { 2 Message m = Message.obtain(); 3 m.callback = r; 4 return m; 5 }
可以看到:其实Post方法是用Runnable参数实例化一个Message然后再调用sendMessageAtTime方法发送到与此Handler关联的那个消息对列中。
主要作用
handler 主要有两个作用:1)安排或调度messages和runnables在将来的某个时间执行。2)将某个行为放到另外一个线程中执行。
其实,handler主要用在子线程与主线程之间的通信。当然也可用在子线程与子线程之间的通信。请看:android多线程与UI操作。在这里主要是想详细的总结一下与handler相关的知识点。
常用方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你安排一个Runnable对象到与之关联的消息队列(一般是主线程)中等待执行,
sendMessage类方法, 允许你安排一个带数据的Message对象到消息队列中,等待处理.
源码分析
Handler关键源码
1 public class Handler { 2 3 //下面三个字段很重要,其实整个Handler都是在和它们打交道 4 final MessageQueue mQueue;//消息队列,handler把消息投递到此队列 5 final Looper mLooper;//消息循环 6 final Callback mCallback;//提供了一个简便的处理message的方法 7 8 //Callback interface you can use when instantiating a Handler to avoid having to implement your own subclass of Handler. 9 //此接口提供了一个简便的处理message的方法,可以使你在需要处理消息时避免一定要去重写handler类handleMessage方法。 10 public interface Callback { 11 public boolean handleMessage(Message msg); 12 } 13 14 //Handler的子类都应该去实现此方法,以达到自定义处理消息的行为 15 public void handleMessage(Message msg) { 16 } 17 18 /**从名字大概能猜到它的作用:用来分发消息。其实从Looper的源码中可以看出此方法在Looper的loop循环中被调用。 19 *第一个if判断此message中是否携带有Runnable,若有则直接执行之并返回,其实此if应该就是针对PostXXX方法设定的。 20 *若没有则接着判断此消息对应的target即handler 21 *是否实现了上面的Callback接口,若实现了,则直接执行之,再根据mCallback.handleMessage(msg)的返回值决定是否接着向下分发 22 *若返回false,或mCallback为null则执行最后的handleMessage(msg);此方法就是我们继承Handler类要去重写的处理消息的方法 23 / 24 public void dispatchMessage(Message msg) { 25 if (msg.callback != null) { 26 handleCallback(msg); 27 } else { 28 if (mCallback != null) { 29 if (mCallback.handleMessage(msg)) { 30 return; 31 } 32 } 33 handleMessage(msg); 34 } 35 } 36 37 38 //handler无参构造方法,此构造方法只能在主线程中用,因为只有主线程默认有looper 39 public Handler() { 40 this(null, false); 41 } 42 43 44 //此构造方法对应上面的Callback接口,通过此构造方法。我们可以不用继承Handler就能处理消息 45 public Handler(Callback callback) { 46 this(callback, false); 47 } 48 49 50 public Handler(Looper looper) { 51 this(looper, null, false); 52 } 53 54 55 public Handler(Looper looper, Callback callback) { 56 this(looper, callback, false); 57 } 58 59 60 /**Handler的一个隐藏构造方法供上面的几个构造方法调用。从中我们也可以看到构造一个handler 61 *需要一个looper,一个此looper管理的消息队列mQueue,callback可有可无,async貌似和同步相关 62 * 63 */ 64 public Handler(Looper looper, Callback callback, boolean async) { 65 mLooper = looper; 66 mQueue = looper.mQueue; 67 mCallback = callback; 68 mAsynchronous = async; 69 } 70 71 //得到以此Handler为target的消息对象 72 public final Message obtainMessage() 73 { 74 return Message.obtain(this); 75 } 76 //post方法用来传递一段代码到目的线程中执行,结合getPostMessage() 77 //方法我们可以看出实际上Handler的postXXX()方法最终发送的也是Message对象 78 //只是将Runnable封装到了Message中 79 public final boolean post(Runnable r) 80 { 81 return sendMessageDelayed(getPostMessage(r), 0); 82 } 83 //以r封装一个新的Message对象 84 private static Message getPostMessage(Runnable r) { 85 Message m = Message.obtain(); 86 m.callback = r; 87 return m; 88 } 89 //sendMessageXXX()方法最终会调用enqueueMessage入队方法 90 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 91 MessageQueue queue = mQueue; 92 if (queue == null) { 93 RuntimeException e = new RuntimeException( 94 this + " sendMessageAtTime() called with no mQueue"); 95 Log.w("Looper", e.getMessage(), e); 96 return false; 97 } 98 return enqueueMessage(queue, msg, uptimeMillis); 99 } 100 101 //被sendMessageXXX()方法所调用,插入message到消息队列中 102 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { 103 msg.target = this; 104 if (mAsynchronous) { 105 msg.setAsynchronous(true); 106 } 107 return queue.enqueueMessage(msg, uptimeMillis); 108 } 109 110 public final void removeMessages(int what) { 111 mQueue.removeMessages(this, what, null); 112 } 113 114 }
上面都是自己这几天上网查资料,接合自己读源码所悟,错误之处还请指正。
Handler的具体实例请参见:


浙公网安备 33010602011771号