Android消息机制

我们在开发中,Handler是我们经常接触的类,在我们用Handler发送处理Message的时候,MessageQueue和Looper一直在他们背后 他们...(哎哟,好基友一辈子嘛)。

平时我们在主线程中使用Handler操作很简单,一套QWER就带走了,所以不再赘述。如果我们在非UI线程中通过Handler的无参数构造函数实例化,会抛出一个Can't create handler inside thread that has not called Looper.prepare()异常。为什么在UI线程就没事,跑到非UI线程就GG了呢?

Handler源码中,其中一个构造函数抛出了这个异常:
public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class 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; }
在Handler没有传入Looper的构造函数中最终都会执行这里。通过Looper.myLooper()获取当前Looper,如果Looper未空就抛出异常。

public static @Nullable Looper myLooper() { return sThreadLocal.get(); }

我们前往Looper类中查看myLooper方法返回了一个Looper的拷贝。再查看prepare方法实际上就是检查了一遍当前线程的Looper是否存在,如果存在则抛出异常,说明一个线程只能有一个Looper,如果不等于null,则新建一个Looper拷贝。
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)); }
如果执行完了prepare之后,初始化Handler对象,在执行loop()方法,

你可能感兴趣的:(Android消息机制)