ThreadLocal存储当前当前线程的Looper对象,作为线程局部变量可以被该线程内任何地方获取到。ThreadLocal作为static final对象被所有Looper对象共享。(可参考上篇 )使用Handler的线程必须是Looper线程,否则抛出异常(构造方法中);或者是NullPointerException。 mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); }一个线程只能调用一次Looper.prepare()。否则会抛出异常(prepare方法中): if (sThreadLocal.get() != null) {//当前线程已经创建了Looper throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed));handler是对外暴漏的,线程间可以互相调用handler发消息。只要持有不同的handler可以。
各个类详解:
Handler
handler的创建方式可以传入Looper对象,即表明该handler是属于哪个线程的,即会回调到哪个线程来处理该message。以下实例为创建UI线程的handler。该技巧可以在其他线程中创建主线程的handler,用于回调到主线程中。 private Handler handler = new Handler(Looper.getMainLooper(), new Handler.Callback() { @Override public boolean handleMessage(Message msg) { return true; } });
Message:
Message类使用对象池模式。主要是使用Message.Obtain()中复用上一个Message,赋值比创建对象快的多。While the constructor of Message is public, the best way to get one of these is to call Message.obtain() or one of the Handler.obtainMessage() methods, which will pull them from a pool of recycled objects.在Looper.loop()方法中,该message被分发到handler中使用完后,会调用msg.recycleUnchecked()方法进行回收。//Looper.loop()中对每个message都调用msg.recycleUnchecked();void recycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }