复习一下消息机制,如下代码:

1
2
3
4
5
6
7
new Thread() {
Handler handler = null;
[@Override](https://my.oschina.net/u/1162528)
public void run() {
handler = new Handler();
}
}.start();

如果执行会抛出异常:

Can’t create handler inside thread Thread.currentThread() that has not called Looper.prepare()

这是为什么呢?

我们进入Handler的构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 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 " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}

从上面的代码我们很清新的可以知道mLooper 为null,那么就会抛出这样的异常,那么mLooper 为什么会为空呢?这是因为在线程中的Looper还未被创建,所以在Looper.myLooper()中sThreadLocal.get()就会返回null。

我们知道 Handler的作用是处理消息,将消息传递给MessageQueue,而MessageQueue存在于Looper中,如果没有Looper那么就没有MessageQueue,所以创建Handler时,Looper不能够为空。

所以以上代码可以进行一个修改:

1
2
3
4
5
6
7
8
9
10
11
private void test() {
new Thread() {
Handler handler = null;
[@Override](https://my.oschina.net/u/1162528)
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
}.start();
}

其中 Looper.prepare();为当前线程创建Looper并绑定在ThreadLocal中
Looper.loop();执行消息循环,这样子 Handler就能够正常工作了。