HandlerThread 是 真正干活的,本身就是一个Thread:
HandlerThread extends Thread
主要比普通的Thread多了一个Looper,而hanlderThread的run函数其实很简单:
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); 这一步就生了该Thread自己的Looper synchronized (this) { mLooper = Looper.myLooper(); mLooper其实一个ThreadLocal变量,每个Thread有自己的一个Looper notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); 在得到Looper以后,就开始无限loop了,直到被要求结束,才会结束run函数,而HandlerThread的生命也结束。 mTid = -1; }
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 这就意味着每个Thread 都有一个自己的sThreadLocal
而sThreadLocal中的Looper是在prepare()时生成的:
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)); }Looper中有
final MessageQueue mQueue; 就是存放要执行的任务, 在构造时生成: mQueue = new MessageQueue(quitAllowed);
final Thread mThread; 记录运行自己的Thread, 在构造的时候就绑定了: mThread = Thread.currentThread();
Looper的quit其实就是mQueue的quit:
public void quit() { mQueue.quit(false); }
而Handler的作用在这里类似于一个对Looper的代理和封装:
首先,handler的构造需要一个Looper, 如果不制定Looper,那么就用当前线程的Looper,因此,在一个Thread使用Handler的前提是该线程的Looper要存在。
public Handler(Callback callback, boolean async) { ........................................................ mLooper = Looper.myLooper(); if (mLooper == null) { 如果当前Thread还没有自己的Looper,那么就 RuntimeException。 throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
比如,post:
post(Runnable r) -> sendMessageDelayed(getPostMessage(r), 0); -> sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)
-> enqueueMessage(queue, msg, uptimeMillis) -> queue.enqueueMessage(msg, uptimeMillis)
这里的queue,就是Looper的MessageQueue。
Looper提供了 loop()<处理任务的方法> 和 MessageQueue<存放待运行任务的队列> , handlerThread 则负责实际的执行<苦力>
而handler则是对上面这个机制的简便性包装.
handler的封装性也体现在对于其enqueueMessage(...)中,这一步会把要enqueue的Message的target设置为handler自己,这样在后面的Looper的loop()中处理Message时,会直接调用msg.target.dispatchMessage(msg), 这样就实现了handler enqueue的Message最后由handler自己来处理.