privateLooper(boolean quitAllowed){ mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
publicvoidquit(){ mQueue.quit(false); } }
classMessageQueue{ voidquit(boolean safe){ //主线程mQuitAllowed值为false,quit时会抛出异常 if (!mQuitAllowed) { thrownew IllegalStateException("Main thread not allowed to quit."); }
publicHandler(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()); } }
//获取Looper对象 mLooper = Looper.myLooper(); //非主线程没有调用Looper.prepare(),则抛出异常 if (mLooper == null) { thrownew RuntimeException( "Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
publicfinalclassLooper{ // sThreadLocal.get() will return null unless you've called prepare(). staticfinal ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); final MessageQueue mQueue; publicstatic@NullableLooper myLooper(){ return sThreadLocal.get(); } publicstaticvoidprepare(){ prepare(true); }
privatestaticvoidprepare(boolean quitAllowed){ //每个线程只能有一个Looper对象,调用prepare会使sThreadLocal.get()==null if (sThreadLocal.get() != null) { thrownew RuntimeException("Only one Looper may be created per thread"); } //准备好消息队列 sThreadLocal.set(new Looper(quitAllowed)); } publicstaticvoidprepareMainLooper(){ prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { thrownew IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } } publicstatic Looper getMainLooper(){ synchronized (Looper.class) { return sMainLooper; } } publicstaticvoidloop(){ final Looper me = myLooper(); if (me == null) { thrownew RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue;
boolean slowDeliveryDetected = false;
for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; }
publicfinalbooleansendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
publicbooleansendMessageAtTime(Message msg, long uptimeMillis){ MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); returnfalse; } return enqueueMessage(queue, msg, uptimeMillis); }
view.post(runnable)
1 2 3 4 5 6 7 8 9 10 11
publicbooleanpost(Runnable action){ final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); }
// Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); returntrue; }