Handle通信机制
一、大致流程
1.在创建Activity之前,应用启动时会加载ActivityThread这个类,这个类就是我经常说的UITherad(主线程),在main()方法中调用Looper(轮询器)的prepareMainLooper()方法,为主线程绑定一个Looper对象。在绑定Looper对象的时候,在Looper的构造函数中创建了一个MessageQueue(消息队列)对象。然后再调用Looper.loop()方法,开启循环。
ActivityThread中的代码:
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();//绑定一个轮询器
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();//开启轮询
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}
Looper中的方法:
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));
}
/**
* Initialize the current thread as a looper, marking it as an
* application's main looper. The main looper for your application
* is created by the Android environment, so you should never need
* to call this function yourself. See also: {@link #prepare()}
*/
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
2.创建Handle,在Handler的构造函数中获取主线程绑定的Looper对象,再从Looper对象中获取MessageQueue对象。
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();// 获得当前线程绑定的looper对象
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;// 获得Looper中创建出来的 messageQueue对象
mCallback = null;
}
3.发送消息,调用sendMessageAtTime(Message msg, long uptimeMillis)方法(其他发送消息的方法都是重载这个方法)。通过MessageQueue对象的enqueueMessage(msg, uptimeMillis)方法,把Message(消息对象)添加到消息队列中。
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;// 获得消息对队
if (queue != null) {
msg.target = this;// 消息的目标就是 当前 handler 对象
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
4.Looper循环已经开启,用一个无限循环从消息队列中取消息,如果没有消息就等待,直到取到消息。当轮询器取到消息的时候,再通过Message对象的target(在发送消息的时候把当前的Handle对象赋值给target,它就是当前的Handle)调用Handle的dispatchMessage(Message msg)方法。在这个方法中执行了handleMessage(msg)方法。
Looper中的方法:
public static final void loop() {
Looper me = myLooper();// 获得当前looper 对象
MessageQueue queue = me.mQueue;// 获得消息队列
while (true) {
Message msg = queue.next();// 从消息对队中取出一个消息 ,如果没有消息,就等待,有消息有时候,再取
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);// 就是执行 handler.handleMessage(msg)方法
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();// 释放,以便于下次利用
}
}
}
Handle中的方法:
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}