privatestaticvoidprepare(boolean quitAllowed) { //如果当前线程已经创建了Looper,那么将抛出异常 //也就是说一个线程只能有一个Looper对象,Looper.prepare()只能调用一次 if (sThreadLocal.get() != null) { thrownewRuntimeException("Only one Looper may be created per thread"); } //如果当前线程没有Looper则,创建一个并保存在当前线程的局部变量中。 sThreadLocal.set(newLooper(quitAllowed)); }
/*********************************************************************************** * 初始化主线程的Looper,该方法在Android系统的入口类 * ActivityThread类中已经被调用了,所以开发者不需要调用这个方法 ***********************************************************************************/ publicstaticvoidprepareMainLooper() { //false代表主线程Looper的消息队列MessageQueue不允许退出 prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { thrownewIllegalStateException("The main Looper has already been prepared."); } //将主线程Looper单独保存在sMainLooper静态变量中 sMainLooper = myLooper(); } }
intpendingIdleHandlerCount= -1; // -1 only during first iteration intnextPollTimeoutMillis=0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); }
// Run the idle handlers. // We only ever reach this code block during the first iteration. for (inti=0; i < pendingIdleHandlerCount; i++) { finalIdleHandleridler= mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler
// Reset the idle handler count to 0 so we do not run them again. pendingIdleHandlerCount = 0;
// While calling an idle handler, a new message could have been delivered // so go back and look again for a pending message without waiting. nextPollTimeoutMillis = 0; } } /*********************************************************************************** *消息队列的退出 ***********************************************************************************/ voidquit(boolean safe) { if (!mQuitAllowed) { thrownewIllegalStateException("Main thread not allowed to quit."); }
// We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); } }
//同步消息拦截(就是放一个target为null的空处理消息进去) intenqueueSyncBarrier(long when) { // Enqueue a new sync barrier token. // We don't need to wake the queue because the purpose of a barrier is to stall it. synchronized (this) { finalinttoken= mNextBarrierToken++; finalMessagemsg= Message.obtain(); msg.markInUse(); msg.when = when; msg.arg1 = token;
//移除同步消息拦截器 voidremoveSyncBarrier(int token) { // Remove a sync barrier token from the queue. // If the queue is no longer stalled by a barrier then wake it. synchronized (this) { Messageprev=null; Messagep= mMessages; while (p != null && (p.target != null || p.arg1 != token)) { prev = p; p = p.next; } if (p == null) { thrownewIllegalStateException("The specified message queue synchronization " + " barrier token has not been posted or has already been removed."); } finalboolean needWake; if (prev != null) { prev.next = p.next; needWake = false; } else { mMessages = p.next; needWake = mMessages == null || mMessages.target != null; } p.recycleUnchecked();
// If the loop is quitting then it is already awake. // We can assume mPtr != 0 when mQuitting is false. if (needWake && !mQuitting) { nativeWake(mPtr); } } }
/*********************************************************************************** * 消息入队 ***********************************************************************************/ booleanenqueueMessage(Message msg, long when) { if (msg.target == null) { //所有的消息必须要有处理对象,当然除了调用enqueueSyncBarrier入队的同步消息拦截器 thrownewIllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { thrownewIllegalStateException(msg + " This message is already in use."); }
synchronized (this) { if (mQuitting) { // 调用quit方法后,消息无法入队,返回false入队失败 IllegalStateExceptione=newIllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w("MessageQueue", e.getMessage(), e); msg.recycle(); returnfalse; }
// 通常新消息插到中间不需要唤醒队列,但如果该消息是拦截器等待的异步消息就不一样啦 needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { //将消息插入到相应时间的合适位置 prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; }
// We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); // 唤醒MessageQueue } } returntrue; }
// 是否符合条件的消息 booleanhasMessages(Handler h, int what, Object object) { if (h == null) { returnfalse; }
synchronized (this) { Messagep= mMessages; while (p != null) { if (p.target == h && p.what == what && (object == null || p.obj == object)) { returntrue; } p = p.next; } returnfalse; } } // 是否符合条件的消息 booleanhasMessages(Handler h, Runnable r, Object object) { if (h == null) { returnfalse; }
synchronized (this) { Messagep= mMessages; while (p != null) { if (p.target == h && p.callback == r && (object == null || p.obj == object)) { returntrue; } p = p.next; } returnfalse; } } // 消息队列是否闲置 booleanisIdling() { synchronized (this) { return isIdlingLocked(); } }
privatebooleanisIdlingLocked() { // If the loop is quitting then it must not be idling. // We can assume mPtr != 0 when mQuitting is false. return !mQuitting && nativeIsIdling(mPtr); }
//移除指定条件的消息(下面的我就不逐行解释了,无非是循环遍历,然后删除结点) voidremoveMessages(Handler h, int what, Object object) { if (h == null) { return; }
synchronized (this) { Messagep= mMessages;
// Remove all messages at front. while (p != null && p.target == h && p.what == what && (object == null || p.obj == object)) { Messagen= p.next; mMessages = n; p.recycleUnchecked(); p = n; }
// Remove all messages after front. while (p != null) { Messagen= p.next; if (n != null) { if (n.target == h && n.what == what && (object == null || n.obj == object)) { Messagenn= n.next; n.recycleUnchecked(); p.next = nn; continue; } } p = n; } } } //移除指定条件的消息 voidremoveMessages(Handler h, Runnable r, Object object) { if (h == null || r == null) { return; }
synchronized (this) { Messagep= mMessages;
// Remove all messages at front. while (p != null && p.target == h && p.callback == r && (object == null || p.obj == object)) { Messagen= p.next; mMessages = n; p.recycleUnchecked(); p = n; }
// Remove all messages after front. while (p != null) { Messagen= p.next; if (n != null) { if (n.target == h && n.callback == r && (object == null || n.obj == object)) { Messagenn= n.next; n.recycleUnchecked(); p.next = nn; continue; } } p = n; } } }