Handler在开发中还是很常用的,通常我们主要用来在子线程中更新UI,其实深入点的话就是涉要另外及Looper、MessageQueue。当然我们也可以让他工作在非UI主线程,怎么用呐?看下边小栗子。
下边我们写个简单的小例子来引入要讲的源码分析。
1 | private class LooperThread extends Thread { |
那么上边的例子Handler工作在哪歌线程中呐??答案是在LooperThread线程,而非主线程。看看以下Handler构造器源码就能明白。
Looper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 public Handler(Callback callback) {
this(callback, 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();//①获取当前的Looper
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;//②获取当前的MassageQueue
mCallback = callback;//③当前的Callback
mAsynchronous = async;
}
那么为什么在UI主线程中使用Handler没有Looper.prepare和Looper.loop()呐??答案就是,在创建Activity时候,系统已经为我们调用了Looper.prepareMainLooper(),所以这个时候在我们UI主线程中直接new Handler()时,Handler就工作在主线程,所以我们就可以用来更新UI界面。
ActivityThread.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public static void main(String[] args) {
......
Looper.prepareMainLooper();//
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
......
}
Looper.java
1
2
3
4
5
6
7
8
9 public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
Looper、Handler准备好了,接下来我们要sendMessage()了,最终会调用到queue.enqueueMessage(msg, uptimeMillis),将Message入队。。。
Handler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 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);
}
最终Looper.loop()会从MessageQueue中轮询Message,然后dispatchMessage()回调到Handler的Callback中dispatchMessage()方法。。。
Looper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
......
for (;;) {
Message msg = queue.next(); // might block
......
try {
msg.target.dispatchMessage(msg);//target即是上边sendMessage()时的handler
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
......
}
}
这样完成了一一个线程的整个的Looper、Handler、MessageQueue流程。。。。