Android handle 更新主线程的原理
1. handler的主要作用是用来更新主线程的UI,子线程向主线程发送信息。
2.handler 的实现原理分析:
1). handler的实现离不开Looper和MessageQueue。一个主线程只创建一个looper与之对应,looper会创建一个MessageQueue用来管理线程间的消息传递。
在looper中有两个很重要的方法,一个是prepare()和loop()。prepare()方法会创建一个Looper对象放到当前线程中,实现一个线程只用一个Looper对象。
在looper的构造方法中会创建一个消息队列,用来存放Message对象。
在loop()方法中首先获取到当前的MessageQueue。并且有一个无线循环 得到队列中的Message( Message msg = queue.next();),当队列是空的时候循环阻塞,
当得到Message 对象后会执行,msg.target.dispatchMessage(msg); 其实这里的msg.target 就是调用sendMessage()的的handler的对象,
2). handler这个对象中的方法有:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
这个方法会调用Handle 中的我们自己实现的 handleMessage方法。
当我们new一个handler的时时候,构造方法会执行以下的方法。
public Handler() {
this(null, false);
}
public Handler(Callback callback, boolean async) {
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();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
这行代码是获取到当前线程的looper,(mLooper = Looper.myLooper();) 在Looper中有 myLooper() 这个静态的方法是得到当前线程的Looper
looper中的代码
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>()
public static Looper myLooper() {
return sThreadLocal.get();
}
Handler类中
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
当我们调用handler中的 sendMessage()时,最终会调用 enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) 这个方法。
这个方法中有 这样的一句 msg.target = this;就可以看出来,msg.targe 就是handler这个对象。这个会在looper 的loop方法中调用 dispatchMessage(Message msg) 这个方法。