浅析Android Handle机制
一.Handle的用例:
1.创建handle实例
new handle();
2.发送信息载体(Message)
sendMessage(msg);
3.处理消息
handleMessage(Message msg){};
二.原理浅析
结合以上的handle调用三部曲,我们将顺藤摸瓜理清Handle、Looper、Message、MessageQueue的逻辑与关系。
1.new Handle():这个操作将生成一个Handle实例,handle实例有三个属性mLooper、mQueue、mCallback,以下解释这三个属性的来历。
1.a:mLooper = Looper.myLooper();Looper的myLooper静态方法也很简单、 public static Looper myLooper() { return sThreadLocal.get(); }
sThreadLocal是一个单例对象,他的类型是ThreadLocal<Looper>,这个类有set()、get()方法,他的作用是当前线程的对象,那么这句代码的作用很明显了就是返回当前线程的Looper对象。再深入一点想,他的set方法在哪里呢?答案是在prepare中:
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
从该方法中可见每个线程中只可以调用一次prepare方法,即每个线程中只有一个Looper对象。
1.b:
mQueue = mLooper.mQueue;Looer对象的mQueue是一个非静态的变量,即:
final MessageQueue mQueue;
他亦在Looper创建时候生成,MessageQueue我们暂时简单理解为消息队列,但是切记他并非等同于:Queue<Message>
1.c:mCallback是一个回调接口,他只有一个方法handleMessage:
public interface Callback { <span style="white-space:pre"> </span>public boolean handleMessage(Message msg); }
这个操作正是他们之间联系的枢纽我们一一来看,首先msg的生成,再看发送msg的动作。
2.a:msg的生成;在Message类中我们看到有个Handle类型的target,所有发送到Handle的msg都会把这个target设置为当前的Handle,如sendMessage()方法最终会有这样一个操作:
msg.target = this;
2.b:sendMessage();无论那个重载方法最终都调用queue.enqueueMessage(msg, uptimeMillis);这个方法中会根据when这个参数来进行排队。即在1.b中的消息队列中排序。
3.handleMessage:处理Message的操作在Looper类中的loop方法中,回顾到1.a我们知道Looper是当前线程的一个单例,即当前线程的所有Message都会再次被处理。Loop方法中有一个死循环将遍历mQueue中的Message并执行dispatchMessage(msg)方法:
msg.target.dispatchMessage(msg);
可见msg的target将处理自己。
方法再次回到Handle类的dispatchMessage方法
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
如果mCallback不为空就执行mCallback的handleMessage方法,否则执行自身的handleMessage方法。
4.总结:Android通过如此巧妙的结构实现了线程间的通信,如果要弄的彻底明白,以Activity为例,在Activity中找到mainThread即我们通常说的主线程,可以清楚的看到looper的创建以及如何进行消息管理。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。