最近面试,总会面到在线程中可以new一个Handler吗?
答案是:不能。
会抛出异常:java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
分析:请看源码
第一步:Handler构造方法
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()方法
public static @Nullable Looper myLooper() { return sThreadLocal.get(); }
返回sThreadLocal.get(),需要查找查找sThreadLocal.set()
第三步:查找sThreadLocal.set()方法
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)); }
看到关键的代码sThreadLocal.set(new Looper(quitAllowed))。也就是说,只有Looper的prepare()被调用的时候,此时才会返回一个Looper对象。Looper.myLooper()才不会返回null。