HandlerThread的使用方法如下:
HandlerThread handlerThread = new HandlerThread("myTest"); handlerThread.start(); Looper looper = handlerThread.getLooper(); Handler handler = new Handler(looper);
为何getLooper方法不会返回空指针呢?
public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
/** * Tests if this thread is alive. A thread is alive if it has * been started and has not yet died. * * @return <code>true</code> if this thread is alive; * <code>false</code> otherwise. */ // Android-changed: Provide pure Java implementation of isAlive(). public final boolean isAlive() { return nativePeer != 0; }
通过源码发现,只要start方法执行了,nativePeer(native层指针)就不会为空。
public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ // Android-changed: Replace unused threadStatus field with started field. // The threadStatus field is unused on Android. if (started) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); // Android-changed: Use field instead of local variable. // It is necessary to remember the state of this across calls to this method so that it // can throw an IllegalThreadStateException if this method is called on an already // started thread. started = false; try { // Android-changed: Use Android specific nativeCreate() method to create/start thread. // start0(); nativeCreate(this, stackSize, daemon); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }
最终HandlerThread初始化Looper后会notifyAll()。
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }