能不能 new Handler?
这里需要从源码出发,在任意java文件中new Handler(),跟进查看Handler源码的具体实现。
public Handler(@Nullable 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();
//注释 1
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;
}
异常信息: that has not called Looper.prepare() 提示我们需要添加Looper.prepare()
注释1:从上面代码可以看出,如果说mLooper 为空的话,这段代码会直接抛出异常,我们可以理解为不能直接new Handler()。那mLooper到底是不是为空呢,这里继续查看Looper.myLooper();
public static @Nullable Looper myLooper() {
//注释 2
return sThreadLocal.get();
}
注释2 : 从这段代码可以看出,Looper是从sThreadLocal中直接取出的,如果对ThreadLocal实现原理有了解,那么很容易就可以看出,如果直接没有存储Looper,这里获取到的肯定为空,那么上面一段代码执行肯定会抛异常;
从上面源码跟踪可以得出结论:如果在子线程没有在ThreadLocal中存储当前线程的Looper,那么Handler是不能被new的。
这里还可以引申看看为什么主线程是可以new Handler的 ,同样查看源码: 查看ActivityThread.java 的main()方法中可以看到如下代码:
public static void main(String[] args) {
... ...
//注释3
Looper.prepareMainLooper();
... ...
}
注释3:这里可以看到在main方法中调用了Looper.prepareMainLooper(),继续跟踪进入
public static void prepareMainLooper() {
//注释4
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
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));
}
注释4:这里调用的是prepare()方法,在prepare()中我们可以看到sThreadLocal.set(new Looper(quitAllowed)); 所以这就是主线程可以直接new Handler的原因。
所以,如果我们在子线程中也调用Loop.prepare()也可以使用new Handler()的。(当然这一点可以从一开始抛出的异常中可以看出。同时需要注意Looper.loop()的使用哦)
回到题目,子线程可以new Handler么,为什么?