//quitAllowed表示该Looper所对应的消息队列是否可退出,具体的退出在Looper.quit()方法里 privatestaticvoidprepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { //表示该线程对应的Looper对象已存在,不能重复调用prepare(),否则就抛异常 thrownewRuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(newLooper(quitAllowed)); }
publicstaticvoidloop() { finalLooperme= myLooper(); if (me == null) { //在这里又判断了一下Looper.prepare()是否调用。 thrownewRuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } finalMessageQueuequeue= me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); finallongident= Binder.clearCallingIdentity(); ... //此处开启一个无限循环,只有当msg == null时才会退出, for (;;) { //调用MessageQueue内部的next()方法,此方法在消息队列为空的时候会执行线程阻塞,阻塞原理是使用Linux的epoll实现的 Messagemsg= queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ... try { //调用handler的dispatchMessage方法来处理消息,最后真正执行到handler的handleMessage() msg.target.dispatchMessage(msg); ... } catch (Exception exception) { if (observer != null) { observer.dispatchingThrewException(token, msg, exception); } throw exception; } finally { ThreadLocalWorkSource.restore(origWorkSource); if (traceTag != 0) { Trace.traceEnd(traceTag); } } ... //使用享元模式来将该Message对象还原并放回消息池中以便将来复用减少内存抖动,具体实现在Message中 msg.recycleUnchecked(); } }
booleanenqueueMessage(Message msg, long when) { //如果没有指定target则不入队抛出异常,其实这里一个是为了后续能定位出需要处理消息的Handler,也为了与同步屏障消息区分开了(这个后说) if (msg.target == null) { thrownewIllegalArgumentException("Message must have a target."); } //如果这个消息已经在入队等待处理往后的流程,那这个消息不能被重复使用直到该消息执行完毕 if (msg.isInUse()) { thrownewIllegalStateException(msg + " This message is already in use."); } //因为同一个线程可以与无数个线程进行通信,所以在入队和出队都必须保证同步 synchronized (this) { //如果正在执行退出操作(也就是Looper.quit()),则不再入队新消息 if (mQuitting) { IllegalStateExceptione=newIllegalStateException( msg.target + " sending message to a Handler on a dead thread"); Log.w(TAG, e.getMessage(), e); msg.recycle(); returnfalse; } // msg.markInUse(); msg.when = when; Messagep= mMessages; boolean needWake; //1.如果队列中还没有消息,则添加队列头并唤醒线程去执行轮训那一套流程取出消息并执行 //2.消息需要立刻执行,则也是唤醒线程执行消息 //3.消息需要执行的时间点比队头消息时间小,那么表示这个消息需要先执行,也执行唤醒执行消息 if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. // 除非队头消息是同步屏障,并且消息是队列中最早的异步消息。否则都不唤醒线程 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); } } returntrue; }
// CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates finalFileconfigDir= Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir);
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. // It will be in the format "seq=114" longstartSeq=0; if (args != null) { for (inti= args.length - 1; i >= 0; --i) { if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { startSeq = Long.parseLong( args[i].substring(PROC_START_SEQ_IDENT.length())); } } } ActivityThreadthread=newActivityThread(); thread.attach(false, startSeq);
if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); }
if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); }
// End of event ActivityThreadMain. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); //开启Looper循环 Looper.loop();
privateintpostSyncBarrier(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;
publicvoidremoveSyncBarrier(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); } } }