Android Message机制
 Android的Message机制,也叫handler机制,主要由3部分+Message组成,这三部分分别是Looper、MessageQueue和Handler。
 Looper:循环体,其作用就是从MessageQueue中取出Message进行消费,一般线程的主体方法的结尾,都会调用Looper的loop方法进入循环,等待处理消息。
 MessageQueue:Message的管理队列,用于保存Message。
 Handler:Message处理的句柄(具体的处理操作)。
Looper
 一般支持Message机制的应用进程或线程,都会调用Looper,如SystemServer和ActivityThread。
 我们先看以下Looper是如何创建。
Looper的创建
// frameworks/base/core/java/android/app/ActivityThread.javapublic static void main(String[] args) {Looper.prepareMainLooper();Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}
 
 以上的代码段是ActivityThread.main方法中对Looper相关代码的提取,可以看到,使用Looper只需简单的两个方法:prepareMainLooper和loop。
 prepareMainLooper是Looper的静态方法,用于创建主线程的Looper对象,从名字上来看,除了主线程,子线程也是可以创建Looper对象。
    public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper != null) {throw new IllegalStateException("The main Looper has already been prepared.");}sMainLooper = myLooper();}}public static void prepare() {prepare(true);}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.prepareMainLooper主要是调用了prepare方法,传参false,表示创建一个不可退出的Looper,这个Looper主要是应用主线程的Looper,由于应用的主线程是不能退出的,主线程的Looper一般都会在主线程的主体结束前调用loop方法,使应用进入循环,保证主线程不会退出,而一旦主线程退出,则应用也就退出。而Looper同时为应用子线程提供了无参的prepare方法,无参的prepare方法就是调用了私有方法Boolean类型的prepare方法,传参true,表示该Looper可退出。
 prepareMainLooper会将创建出来的Looper保存到sMainLooper中供应用其他的子线程快速获取。
 带参prepare方法中会判断线程是否已经创建过Looper,Android只允许每个线程有一个Looper,这个是合理的设计,因为每个线程最多只能无限执行一个循环。
 带参prepare方法中,使用了ThreadLocal泛型类型,以支持每个线程都能创建Looper,ThreadLocal有一个数组保存了每个线程的Looper对象,在不同的线程中调用sThreadLocal.get()获取的Looper都是不一样的。具体可参考libcore/ojluni/src/main/java/java/lang/ThreadLocal.java 。
 Looper实例的构建比较简单,主要是创建了MessageQueue实例和记录当前的Thread对象,这里就不展开说明。
Looper.loop
 Looper.loop是整个Looper的核心,我们在这里分析整个loop的过程,了解这当中的细节。
    public static void loop() {final Looper me = myLooper();if (me == null) {throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");}final MessageQueue queue = 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();final long ident = Binder.clearCallingIdentity();// Allow overriding a threshold with a system prop. e.g.// adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'final int thresholdOverride =SystemProperties.getInt("log.looper."+ Process.myUid() + "."+ Thread.currentThread().getName()+ ".slow", 0);boolean slowDeliveryDetected = false;for (;;) {Message msg = queue.next(); // might blockif (msg == null) {// No message indicates that the message queue is quitting.return;}// This must be in a local variable, in case a UI event sets the loggerfinal Printer logging = me.mLogging;if (logging != null) {logging.println(">>>>> Dispatching to " + msg.target + " " +msg.callback + ": " + msg.what);}// Make sure the observer won't change while processing a transaction.final Observer observer = sObserver;final long traceTag = me.mTraceTag;long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;if (thresholdOverride > 0) {slowDispatchThresholdMs = thresholdOverride;slowDeliveryThresholdMs = thresholdOverride;}// logSlowDelivery和logSlowDispatch是处理dispatch和delivery较慢的消息。final boolean logSlowDelivery = (slowDeliveryThresholdMs > 0) && (msg.when > 0);final boolean logSlowDispatch = (slowDispatchThresholdMs > 0);final boolean needStartTime = logSlowDelivery || logSlowDispatch;final boolean needEndTime = logSlowDispatch;if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {Trace.traceBegin(traceTag, msg.target.getTraceName(msg));}final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;final long dispatchEnd;Object token = null;if (observer != null) {token = observer.messageDispatchStarting();}long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid);try {msg.target.dispatchMessage(msg);if (observer != null) {observer.messageDispatched(token, msg);}dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;} catch (Exception exception) {if (observer != null) {observer.dispatchingThrewException(token, msg, exception);}throw exception;} finally {ThreadLocalWorkSource.restore(origWorkSource);if (traceTag != 0) {Trace.traceEnd(traceTag);}}if (logSlowDelivery) {if (slowDeliveryDetected) {if ((dispatchStart - msg.when) <= 10) {Slog.w(TAG, "Drained");slowDeliveryDetected = false;}} else {if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",msg)) {// Once we write a slow delivery log, suppress until the queue drains.slowDeliveryDetected = true;}}}if (logSlowDispatch) {showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", msg);}if (logging != null) {logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);}// Make sure that during the course of dispatching the// identity of the thread wasn't corrupted.final long newIdent = Binder.clearCallingIdentity();if (ident != newIdent) {Log.wtf(TAG, "Thread identity changed from 0x"+ Long.toHexString(ident) + " to 0x"+ Long.toHexString(newIdent) + " while dispatching to "+ msg.target.getClass().getName() + " "+ msg.callback + " what=" + msg.what);}msg.recycleUnchecked();}}
 
 loop方法中代码很多,但很多都是非重点代码,都是一些调试log的代码,真正的核心代码只有以下2行:
Message msg = queue.next(); // might block
msg.target.dispatchMessage(msg);
 
 loop就是进入一个死循环体中,不断地从MessageQueue中取出Message进行消费,消费就是调用Message中的target(Handler)的dispatchMessage方法进行处理。
Looper中的设计特点
 Looper中有一些设计是非常妙的,我们来总结一下。
 1.Looper的构造方法是private修饰的,意味着,外部无法实例化Looper,只能通过Looper类提供的静态方法进行创建,类似于单例模式。
 2.Looper中使用的设计模式又并非单例模式,因为一个进程中,是允许有多个Looper实例对象的。
Message和Handler
 MessageQueue的代码更为复杂,我们先来看看MessageQueue的数据是怎么使用的。
 我们以ActivityThread内部发送Message的源码来进行抛砖引玉。
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {Message msg = Message.obtain();msg.what = what;msg.obj = obj;msg.arg1 = arg1;msg.arg2 = arg2;if (async) {msg.setAsynchronous(true);}mH.sendMessage(msg);
}
 
 ActivityThread的sendMessage方法中,主要是通过Message.obtain()方法生成一个空的Message,然后填充what字段(必须)以及其他选填数据,最后通过Handler的sendoMessage方法发送消息。值得注意的是,Message中有setAsynchronous方法,表明Message的处理或者分发应该支持异步的操作。
 Message的发送在这里我们重点关注2点:①Message的创建方式有多少种,里面有什么重要的信息。②Handler发送Message的方式有多少种,以及发送Message的过程是怎样的。
Message的创建
 我们先来看看Message的类图:

 Message中构造函数是public修饰的,表明其可以外部new出对象,但Message类提供了多个obtain的静态重载方法。其中主要看它们的参数,有几个重要的参数组合,无参方法表示只new出一个纯粹的Message对象,需要用户自行填充数据。带有Message对象参数的方法,将obtain一个Message,然后将参数Message中的数据copy到新的Message中。剩下的几个就是赋予不同参数的obtain方法,将这些参数赋值到Message的变量中。
 其中有几个比较重要的变量:what(Message的类型,识别Message的重要变量)、arg1和arg2(Message的参数,可不设置)、obj(传递的一些数据对象)、flag(一些标志,如异步)、target(Handler,处理Message的一种方式)、callback(Runnable,处理Message的一种方式)、next和sPool(Message的缓存池,在一个进程中,Message并不是每次都会new出新的对象,以减少内存的开销)。sendToTarget方法,用于Message的发送。
Message的设计特点
 Message中使用了缓存池的设计思想,是值得我们思考和参考的,我们来具体看一下。
 Message的多个obtain方法,都会调用到无参的obtain方法,而无参的obtain方法就是使用缓存池的核心。
public static Message obtain() {synchronized (sPoolSync) {   //持锁,保证申请/创建Message对象是原子操作if (sPool != null) {Message m = sPool;sPool = m.next;m.next = null;m.flags = 0; // clear in-use flagsPoolSize--;return m;}}return new Message();
}
 
 Message中的缓存池使用的是单链表的方式实现,sPool就是这个链表的表头,next就是指向下一个节点的指针,当调用obtain时,如果sPool非空,即缓存池中有Message实例对象时,则可直接获取该对象来使用,同时将这个实例对象的next指针赋值给sPool,此时这个实例对象就从缓存池中被取出。这个缓存池的大小是MAX_POOL_SIZE(50),那么这缓存池中的实例对象时从哪来的呢?其来源就是当Message被处理完后,调用recycleUnchecked,丢到缓存池中备用:
void recycleUnchecked() {// Mark the message as in use while it remains in the recycled object pool.// Clear out all other details.flags = FLAG_IN_USE;what = 0;arg1 = 0;arg2 = 0;obj = null;replyTo = null;sendingUid = UID_NONE;workSourceUid = UID_NONE;when = 0;target = null;callback = null;data = null;synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;sPool = this;sPoolSize++;}}
}
 
 recycleUnchecked的前半部分都是将Message实例的数据reset,如果目前缓存池的数量已经达到上限,则抛弃这个实例,由虚拟机的GC进行回收,否则加入到缓存池的链表头中,等待obtain方法被调用时再次使用。
Handler的消息发送
 Handler的类图如下:

 Handler的作用主要是分发消息和处理消息,同样,也可以通过Handler来实例化Message对象。我们主要关注Handler的一下方法:
 1.post系列方法,用于发送消息,实际上底层也是调用到sendMessage。
 2.sendMessage系列方法,用于发送消息。
 3.dispatchMessage,分发消息。
 4.handleMessage,处理消息,Handler默认空实现,用户一般会实现一个继承Handler的子类,重写handleMessage方法,进而处理消息。
 5.removeMessages和removeCallbacksAndMessages,用于删除指定的一类消息。
post
 我们先来看一下post系列的方法,以两个典型为例看一下;
public final boolean post(@NonNull Runnable r) {return  sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
private static Message getPostMessage(Runnable r) {Message m = Message.obtain();m.callback = r;return m;
}
 
 Handler的post方法和postAtTime方法,传参都是Runnable类型的实例,postAtTime则是添加了事件戳,两者的底层都是调用到sendMessage系列的方法。而post系统发送的消息,由getPostMessage方法来生成。从post系列的方法中可以看到,post的Message的处理都是Runnable的方式。
sendMessage
 我们再来看看sendMessage方法的实现,这个是我们的重点方法,我们也还是以两个典型方法来分析:
public final boolean sendMessage(@NonNull Message msg) {return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {if (delayMillis < 0) {delayMillis = 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(@NonNull 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);return false;}return enqueueMessage(queue, msg, uptimeMillis);
}
public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {MessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}return enqueueMessage(queue, msg, 0);
} 
 不论是sendMessage、sendMessageDelay、sendMessageAtTime或者sendMessageAtFrontOfQueue,其最终都是调用enqueueMessage方法将Message压入到MessageQueue中:
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,long uptimeMillis) {msg.target = this;msg.workSourceUid = ThreadLocalWorkSource.getUid();if (mAsynchronous) {msg.setAsynchronous(true);}return queue.enqueueMessage(msg, uptimeMillis);
} 
 其中Message在MessageQueue中的位置是由uptimeMillis参数来决定,MessageQueue中的Message是由消息处理的时间戳来排序的,因此sendMessageAtFrontOfQueue方法中,uptimeMillis为0,表示立即处理。至于Message是如何压入到MessageQueue部分的逻辑,我们放到MessageQueue的代码中进行分析。
dispatchMessage
public void dispatchMessage(@NonNull Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}
} 
 dispacthMessage的逻辑十分简单,如果Message有设置自身有设置callback(Runnable实例),则执行运行callback。否则会交由Handler进行处理。Handler在构造的时候可以传入Callback实例,这样就会优先使用Callback来进行处理,如下:
// frameworks/base/core/java/android/view/LayoutInflater.java
mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {if (msg.what == MESSAGE_BLINK) {if (mBlink) {mBlinkState = !mBlinkState;makeBlink();}invalidate();return true;}return false;}
}); 
 否则就调用handleMessage方法,一般由用户自定义实现,如下:
// frameworks/base/wifi/java/android/net/wifi/WifiManager.java
mHandler = new Handler(looper) {@Overridepublic void handleMessage(Message msg) {WifiManager manager = mWifiManager.get();if (manager == null) {Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC");return;}switch (msg.what) {case HOTSPOT_STARTED:WifiConfiguration config = (WifiConfiguration) msg.obj;if (config == null) {Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);return;}callback.onStarted(manager.new LocalOnlyHotspotReservation(config));break;case HOTSPOT_STOPPED:Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");callback.onStopped();break;case HOTSPOT_FAILED:int reasonCode = msg.arg1;callback.onFailed(reasonCode);Log.w(TAG, "done with the callback...");break;default:Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message.  type: "+ msg.what);}}
}; 
 Message是怎么走到Handler的?这个可以往前参考Looper.loop和Handler.enqueueMessage,enqueueMessage将Message的target变量设置成Handler的实例,在Looper中的loop方法,从MessageQueue中取出Message后就会调用其target变量的dispatchMessage方法,这样就走到了这里来。
 removeMessages方法比较简单,主要跟MessageQueue相关,我们放到MessageQueue的分析时再看。
MessageQueue
 MessageQueue是Android Message机制的核心,也是最复杂的部分,我们仔细分析一下这里。下面是MessageQueue的类图:

 MessageQueue的代码涉及了Java部分和native部分,我们还是分几条主线来进行分析:
 1.MessageQueue的创建。
 2.消息的来源 – enqueueMessage
 3.消息的分发处理
 4.消息的remove
 5.设计特点
MessageQueue的创建
 再Looper的创建的时候已经看到,MessageQueue的实例就是在Looper的创建时创建的:
MessageQueue(boolean quitAllowed) {mQuitAllowed = quitAllowed;mPtr = nativeInit();
} 
 MessageQueue跟Looper是绑定的,一个Looper有一个MessageQueue。在主Looper中,MessageQueue的mQuitAllowed为false,非主Looper则可为true。nativeInit是native的方法:
static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();if (!nativeMessageQueue) {jniThrowRuntimeException(env, "Unable to allocate native queue");return 0;}nativeMessageQueue->incStrong(env);return reinterpret_cast<jlong>(nativeMessageQueue);
} 
 MessageQueue在构造时会创建一个native层对应的实例 – NativeMessageQueue,然后将这个实例的native地址返回。下面是NativeMessageQueue以及相关类的类图:

 NativeMessageQueue以及其相关的类跟Java层的MessageQueue和Looper是不是十分的像。接下来的内容与就是分析native层的内容。
NativeMessageQueue::NativeMessageQueue() :mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {mLooper = Looper::getForThread();if (mLooper == NULL) {mLooper = new Looper(false);Looper::setForThread(mLooper);}
}
NativeMessageQueue::NativeMessageQueue() :mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {mLooper = Looper::getForThread();if (mLooper == NULL) {mLooper = new Looper(false);Looper::setForThread(mLooper);}
} 
 NativeMessageQueue在构造时就会获取/创建一个native层的Looper实例,而这个实例是绑定线程的,也就是说,一个线程只能有一个native层的Looper实例,这与Java层的Looper是一样的。native层的Looper从名字上来看,其就是一个消息的驱动器,用于消息的运转。
Looper::Looper(bool allowNonCallbacks): mAllowNonCallbacks(allowNonCallbacks),mSendingMessage(false),mPolling(false),mEpollRebuildRequired(false),mNextRequestSeq(0),mResponseIndex(0),mNextMessageUptime(LLONG_MAX) {mWakeEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));LOG_ALWAYS_FATAL_IF(mWakeEventFd.get() < 0, "Could not make wake event fd: %s", strerror(errno));AutoMutex _l(mLock);rebuildEpollLocked();
} 
 Looper实现中有两种文件:eventfd和epoll_fd。eventfd用于唤醒Looper,epoll_fd则是用于监听消息。event_fd由eventfd方法创建,epoll_fd由rebuildEpollLocked方法创建:
void Looper::rebuildEpollLocked() {// Close old epoll instance if we have one.if (mEpollFd >= 0) {
#if DEBUG_CALLBACKSALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this);
#endifmEpollFd.reset();}// Allocate the new epoll instance and register the wake pipe.mEpollFd.reset(epoll_create1(EPOLL_CLOEXEC));LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));struct epoll_event eventItem;memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field unioneventItem.events = EPOLLIN;eventItem.data.fd = mWakeEventFd.get();int result = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mWakeEventFd.get(), &eventItem);LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s",strerror(errno));for (size_t i = 0; i < mRequests.size(); i++) {const Request& request = mRequests.valueAt(i);struct epoll_event eventItem;request.initEventItem(&eventItem);int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, request.fd, &eventItem);if (epollResult < 0) {ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s",request.fd, strerror(errno));}}
} 
 rebuildEpollLocked将mWakeEventFd加入到mEpollFd的监听队列中。还有mRequests的文件描述符,但在常用的Message消息处理中并没有使用到,我们在本文档的最后一章使用NetworkStack的例子来进行分析。本章则先跳过。
 至此,MessageQueue已经在native层构建好了一个Message驱动的框架。
消息的来源 – enqueueMessage
 Message的发送在前面Message和Handler的一章中已经分析过,Message的sendToTarget方法、Handler的post和sendMessage系列方法,都可以发送Message,其最终都是调用到MessageQueue的enqueueMessage方法:
boolean enqueueMessage(Message msg, long when) {if (msg.target == null) {throw new IllegalArgumentException("Message must have a target.");}if (msg.isInUse()) {throw new IllegalStateException(msg + " This message is already in use.");}synchronized (this) {if (mQuitting) {IllegalStateException e = new IllegalStateException(msg.target + " sending message to a Handler on a dead thread");Log.w(TAG, e.getMessage(), e);msg.recycle();return false;}msg.markInUse();msg.when = when;Message p = mMessages;boolean needWake;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.nextprev.next = msg;}// We can assume mPtr != 0 because mQuitting is false.if (needWake) {nativeWake(mPtr);}}return true;
} 
 MessageQueue对Message的管理使用的是单链表结构,mMessages就是这个链表结构的链表头。从上述代码上看到,enqueueMessage分了两类情况:
 1.将Message压入到链表头中。
 1).当前的链表已经没有数据(mMessages为null)。
 2).enqueue的Message的时间戳为0,表示当前立即处理的消息。
 3).enqueue的Message的时间戳比链表头的Message的时间戳更为早(链表中Message的排序是按照时间戳的顺序进行排序,链表头的Message时间戳必定是最早的)。
 这种情况下needWake的值为mBlocked,表示如果当前MessageQueue正处于阻塞状态,则需要唤醒以检查是否已有需要处理的Message。
 2.为Message排序,将其插入到链表中合适的位置。
 这种情况下needWake的值是根据链表中表头Message和当前Message以及插入位置的前一些Message的属性来确定。
 1).如果当前queue不是阻塞状态,则无需唤醒queue,needWake为false。
 2).如果queue处于阻塞状态,且表头的Message没有Handler。但从Handler的enqueueMessage方法中可以看到,正常使用这是不可能发生的,除非是我们自己修改的。
 3).当前的Message是异步的。满足以上3点,则neddWake为true。
 4).如果前面三点都符合,needWake的值为true,但再插入Message的过程中,发现插入位置前的Message是异步的,这是由于异步的性质决定的。我们在后面分析一下这个异步会带来什么行为。
 经过前面的插入到链表的操作后,如果needWake为true,则调用nativeWake方法,最后调用到native层的Looper对象的wake方法。
void Looper::wake() {uint64_t inc = 1;ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd.get(), &inc, sizeof(uint64_t)));
} 
 Looper.wake会往mWakeEventFd文件节点中写入值,以唤醒Looper的epoll。
消息的分发处理
 在Java层的Looper.loop分析中,得知Looper分发事件的Message来源是通过MessageQueue.next()方法来获取。
Message next() {final long ptr = mPtr;int pendingIdleHandlerCount = -1; // -1 only during first iterationint nextPollTimeoutMillis = 0;for (;;) {nativePollOnce(ptr, nextPollTimeoutMillis);synchronized (this) {// Try to retrieve the next message.  Return if found.final long now = SystemClock.uptimeMillis();Message prevMsg = null;Message msg = mMessages;if (msg != null && msg.target == null) {// Stalled by a barrier.  Find the next asynchronous message in the queue.do {prevMsg = msg;msg = msg.next;} while (msg != null && !msg.isAsynchronous());}if (msg != null) {if (now < msg.when) {// Next message is not ready.  Set a timeout to wake up when it is ready.nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);} else {// Got a message.mBlocked = false;if (prevMsg != null) {prevMsg.next = msg.next;} else {mMessages = msg.next;}msg.next = null;if (DEBUG) Log.v(TAG, "Returning message: " + msg);msg.markInUse();return msg;}} else {// No more messages.nextPollTimeoutMillis = -1;}// If first time idle, then get the number of idlers to run.// Idle handles only run if the queue is empty or if the first message// in the queue (possibly a barrier) is due to be handled in the future.if (pendingIdleHandlerCount < 0&& (mMessages == null || now < mMessages.when)) {pendingIdleHandlerCount = mIdleHandlers.size();}if (pendingIdleHandlerCount <= 0) {// No idle handlers to run.  Loop and wait some more.mBlocked = true;continue;}if (mPendingIdleHandlers == null) {mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];}mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);}// Run the idle handlers.// We only ever reach this code block during the first iteration.for (int i = 0; i < pendingIdleHandlerCount; i++) {final IdleHandler idler = mPendingIdleHandlers[i];mPendingIdleHandlers[i] = null; // release the reference to the handlerboolean keep = false;try {keep = idler.queueIdle();} catch (Throwable t) {Log.wtf(TAG, "IdleHandler threw exception", t);}if (!keep) {synchronized (this) {mIdleHandlers.remove(idler);}}}// 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;}
} 
 从Looper.loop()方法调用MessageQueue.next()方法时的注释可得知,该方法是一个会进入阻塞状态的方法。next()方法中有两个重要的局部变量 – pendingIdleHandlerCount和nextPollTimeoutMillis。pendingIdleHandlerCount表示当前需要处理的Idlehandler的数量,当MessageQueue中没有需要立即处理分发的Messages,就会执行mIdleHandlers中注册的Idlehandler。nextPollTimeoutMillis表示下一次poll等待的时间,这个是epoll_wait的timeout参数,当值为0时,表示立即返回,不进行阻塞;当值为-1时,表示阻塞到有数据;当值大于0时,表示则是nextPollTimeoutMillis个ms时间。
 当next()方法刚进入时,nextPollTimeoutMillis为0,调用nativePollOnce()本地方法(实际上是调用到(native层的Looper.pollOnce()方法)。Looper.pollInner()方法比较长,我们精简出我们要的逻辑代码。
int Looper::pollInner(int timeoutMillis) {// Adjust the timeout based on when the next message is due.if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);if (messageTimeoutMillis >= 0&& (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {timeoutMillis = messageTimeoutMillis;}}// Poll.int result = POLL_WAKE;// We are about to idle.mPolling = true;struct epoll_event eventItems[EPOLL_MAX_EVENTS];int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);// No longer idling.mPolling = false;// Acquire lock.mLock.lock();// Handle all events.for (int i = 0; i < eventCount; i++) {int fd = eventItems[i].data.fd;uint32_t epollEvents = eventItems[i].events;if (fd == mWakeEventFd.get()) {if (epollEvents & EPOLLIN) {awoken();} else {ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);}}}
Done: ;// Release lock.mLock.unlock();return result;
} 
 从Looper.pollInner()方法中提取出以上跟消息的分析有关的逻辑代码。
 正常情况下,timeoutMillis为传入参数的值,这个变量的值被传入到epoll_wait中。第一次传入的值为0,表示epoll_wait不会进行阻塞等待数据,只会检查一下是否有数据,会出现两种情况:
 1.此时没有数据,eventCount = 0,直接返回。
 2.此时有数据,且是mWakeEventFd的数据,则调用awoken()方法。
 第二种情况使用于后面阻塞的场景,因此在后面分析。按照第一种情况,nativePollOnce()方法直接返回,我们继续回到next()方法分析。
 当nativePollOnce()返回后,next()方法就会去比较当前的时间与Messages链表头的Message的时间戳,如果当前时间已经到了头Message的时间戳,则表明是时候处理这个消息了,处理好链表的删除操作后,将这个Message返回,已供Looper去分发处理。当时间还没到最近一个Message的处理时间,则计算需要等待的时间(如果当前Messages链表中没有消息,则为-1)。
 此时next()方法并不是直接进入nativePollOnce()方法去等待,而是去查看一下是否有pending的Idlehandlers需要去处理,Idlehandlers顾名思义,就是在MessageQueue空闲的时候进行处理的事务,当当前没有需要立即处理的消息(Messages链表为null或者当前的Message处理的时间还没到),此时才会去进行处理。而且我们可以看到pendingIdleHandlerCount这个值只有在next()方法的第一次循环时才会小于0.
 假设此时MessageQueue空闲,且处理完IdleHandler的事务后,next()方法会再次进行循环,但此时nextPollTimeoutMillis的值会被重新清零,因为此时有可能最近的一次Message已经到时间去处理了。
 当nextPollTimeoutMillis的值为非零值时,我们再回到native层的Looper.pollInner()方法中,此时epoll_wait则将会等待超时来处理下一个Message,或者被一个新的更优先处理的Message进来打断去处理(enqueueMessage()方法的分析种有说明)。第一种情况则直接返回,第二种情况则会调用native层的Looper.awoken()方法去清除掉mWakeEventFd的内容。
 被打断的情况有可能时立即需要处理的Message,此种情况则立即将该Message返回到Java层的Looper.loop()方法。如果是并非立即处理的Message,则会重新计算nextPollTimeoutMillis的值,再次进入到阻塞状态。
 经过Java层的Looper.loop()方法和MessageQueue.next()方法的配合,Message的分发处理就是这样不断地流转。
消息的remove
 消息的remove只是一个概括,从前面的Handler和MessageQueue的类图中可以看到有一些对Message的处理 – 判断队列(链表)中是否有什么类型的Messages(hasMessages)和删除一个类型的Messages(removeMessages、removeCallbacksAndMessages等)。甚至包括enqueueMessage,其实都是对单链表的常用操作。我们这里就不再展开分析。
MessageQueue中的IdleHandler
 我们在MessageQueue.next()方法中可以看到IdleHandler的使用,但我们还没有以具体的例子来进行分析其作用,因此在这一节中使用ActivityThread的源码来进行分析:
2040:    private class Idler implements MessageQueue.IdleHandler {
2079:    final class GcIdler implements MessageQueue.IdleHandler {
2088:    final class PurgeIdler implements MessageQueue.IdleHandler { 
 以AndroidQ版本的源码来看,ActivityThread中有三个实现继承了MessageQueue.IdleHandler。我们本节不展开说明这三个IdleHandler的具体作用,只看与MessageQueue相关的操作,我们找比较简单的GcIdle来进行简单分析:
final class GcIdler implements MessageQueue.IdleHandler {@Overridepublic final boolean queueIdle() {doGcIfNeeded();purgePendingResources();return false;}
}
final GcIdler mGcIdler = new GcIdler();
void scheduleGcIdler() {if (!mGcIdlerScheduled) {mGcIdlerScheduled = true;Looper.myQueue().addIdleHandler(mGcIdler);}mH.removeMessages(H.GC_WHEN_IDLE);
}void unscheduleGcIdler() {if (mGcIdlerScheduled) {mGcIdlerScheduled = false;Looper.myQueue().removeIdleHandler(mGcIdler);}mH.removeMessages(H.GC_WHEN_IDLE);
} 
 在ActivityThread的代码中与GcIdler相关的代码只有上面几行,我们可以看到使用MessageQueue.IdleHandler的步骤主要有下面3步:
 1.实现MessageQueue.IdleHandler,重写queueIdle()方法,以实现自己想要的功能。queueIdle()的返回值表示这个Handler是否在被执行后继续保存在MessageQueue中,true表示可不断被执行,false表示只执行一次。
 2.在适当的时机将这个IdleHandler实例注册到MessageQueue中,调用MessageQueue.addIdleHandler()方法注册。
 3.在适当的时机将这个IdleHandler实例从MessageQueue中注销,调用MessageQueue,removeIdleHandler()方法注销。
设计特点
 MessageQueue的核心在这里有两个核心点 : 使用单链表的数据结构管理Message以及使用native层的epoll机制(native层Looper)。这两者的相互配合,使得Message机制得以运行。
native层Looper
MessageQueue.addOnFileDescriptorEventListener
 MessageQueue还提供了监听文件节点的功能,我们这一章主要分析一下这个功能的实现方式及其作用,结合NetworkStack的应用场景来看看是怎么使用这个功能的。
 在NetworkStack的源码中搜索addOnFileDescriptorEventListener,可以找到只有一处在使用:
// packages/modules/NetworkStack/src/android/net/util/FdEventsReader.java
private void createAndRegisterFd() {if (mFd != null) return;try {mFd = createFd();} catch (Exception e) {logError("Failed to create socket: ", e);closeFd(mFd);mFd = null;}if (mFd == null) return;mQueue.addOnFileDescriptorEventListener(mFd,FD_EVENTS,(fd, events) -> {// Always call handleInput() so read/recvfrom are given// a proper chance to encounter a meaningful errno and// perhaps log a useful error message.if (!isRunning() || !handleInput()) {unregisterAndDestroyFd();return UNREGISTER_THIS_FD;}return FD_EVENTS;});onStart();
} 
 FdEventsReader是一个抽象类,createFd是一个抽象方法,在这里主要是有两个重点:①调用createFd创建一个文件节点,这个文件节点肯定是一个类似与pipe之类的多端文件通道。②调用MessageQueue.addOnFileDescriptorEventListener注册文件监听器,实现OnFileDescriptorEventListener接口类的onFileDescriptorEvents()方法,这里使用的是lamda表达式。
 FdEventsReader有两个实现类,我们以其中一个来看:
// packages/modules/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
@Override
protected FileDescriptor createFd() {FileDescriptor fd = null;try {fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE);Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));NetlinkSocket.connectToKernel(fd);if (VDBG) {final SocketAddress nlAddr = Os.getsockname(fd);Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}");}} catch (ErrnoException|SocketException e) {logError("Failed to create rtnetlink socket", e);NetworkStackUtils.closeSocketQuietly(fd);return null;}return fd;
} 
 createFd()方法创建了一个socket,socket大部分人都使用过,这里创建的是Netlink的socket,然后将这个socket fd返回。
 我们再看会MessageQueue的addOnFileDescriptorEventListener()方法。
public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,@OnFileDescriptorEventListener.Events int events,@NonNull OnFileDescriptorEventListener listener) {synchronized (this) {updateOnFileDescriptorEventListenerLocked(fd, events, listener);}
}
private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,OnFileDescriptorEventListener listener) {final int fdNum = fd.getInt$();int index = -1;FileDescriptorRecord record = null;if (mFileDescriptorRecords != null) {index = mFileDescriptorRecords.indexOfKey(fdNum);if (index >= 0) {record = mFileDescriptorRecords.valueAt(index);if (record != null && record.mEvents == events) {return;}}}if (events != 0) {events |= OnFileDescriptorEventListener.EVENT_ERROR;if (record == null) {if (mFileDescriptorRecords == null) {mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();}record = new FileDescriptorRecord(fd, events, listener);mFileDescriptorRecords.put(fdNum, record);} else {record.mListener = listener;record.mEvents = events;record.mSeq += 1;}nativeSetFileDescriptorEvents(mPtr, fdNum, events);} else if (record != null) {record.mEvents = 0;mFileDescriptorRecords.removeAt(index);nativeSetFileDescriptorEvents(mPtr, fdNum, 0);}
} 
 updateOnFileDescriptorEventListenerLocked()方法有三个传参:①文件描述符fd;②所要监听的事件类型;③监听回调OnFileDescriptorEventListener接口类实现。同时updateOnFileDescriptorEventListenerLocked也是removeOnFileDescriptorEventListener()所调用的方法,add和remove的区别就是监听事件类型,只要监听的事件类型不为0,则表示注册监听事件,为0表示注销监听。
 事件的类型分为三类:EVENT_INPUT(输入事件,可读取状态);EVENT_OUTPUT(输出事件,写入状态);EVENT_ERROR(异常状态)。
 updateOnFileDescriptorEventListenerLocked的实现比较简单,主要是根据注册/注销操作对mFileDescriptorRecords(内部实现就是两个数组保存keys和values,keys为int类型数据,然后根据keys的索引来找到value)进行管理。然后调用nativeSetFileDescriptorEvents去更新native层的数据:
void NativeMessageQueue::setFileDescriptorEvents(int fd, int events) {if (events) {int looperEvents = 0;if (events & CALLBACK_EVENT_INPUT) {looperEvents |= Looper::EVENT_INPUT;}if (events & CALLBACK_EVENT_OUTPUT) {looperEvents |= Looper::EVENT_OUTPUT;}mLooper->addFd(fd, Looper::POLL_CALLBACK, looperEvents, this,reinterpret_cast<void*>(events));} else {mLooper->removeFd(fd);}
} 
 MessageQueue中的文件节点的监听实际上使用的是native层Looper监听文件节点的方式,这个是InputFlinger中InputDispatcher的实现类似,我们这里也步展开分析,只看一下native层Looper除了在Message机制中的作用外监听文件节点的功能。
Looper.addFd和Looper.removeFd
int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : nullptr, data);
}
int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {if (!callback.get()) {if (! mAllowNonCallbacks) {ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");return -1;}if (ident < 0) {ALOGE("Invalid attempt to set NULL callback with ident < 0.");return -1;}} else {ident = POLL_CALLBACK;}{ // acquire lockAutoMutex _l(mLock);Request request;request.fd = fd;request.ident = ident;request.events = events;request.seq = mNextRequestSeq++;request.callback = callback;request.data = data;if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1struct epoll_event eventItem;request.initEventItem(&eventItem);ssize_t requestIndex = mRequests.indexOfKey(fd);if (requestIndex < 0) {int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem);if (epollResult < 0) {ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));return -1;}mRequests.add(fd, request);} else {int epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_MOD, fd, &eventItem);if (epollResult < 0) {if (errno == ENOENT) {epollResult = epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, fd, &eventItem);if (epollResult < 0) {ALOGE("Error modifying or adding epoll events for fd %d: %s",fd, strerror(errno));return -1;}scheduleEpollRebuildLocked();} else {ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));return -1;}}mRequests.replaceValueAt(requestIndex, request);}} // release lockreturn 1;
} 
 addFd和removeFd的代码其实很简单,addFd主要是是将文件描述符fd和NativeMessageQueue实例绑定成Request结构,加入到Looper.mRequests数组中,并将fd添加到epoll的监听队列中去。removeFd则是相反的操作。
Looper.pollInner
 我们又回到Looper.pollInner()方法,在这里,epoll_wait监听这我们所注册进来的fd,以下是我们提取出跟Request相关的代码:
int Looper::pollInner(int timeoutMillis) {// Poll.int result = POLL_WAKE;mResponses.clear();mResponseIndex = 0;// We are about to idle.mPolling = true;struct epoll_event eventItems[EPOLL_MAX_EVENTS];int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);// No longer idling.mPolling = false;// Acquire lock.mLock.lock();// Rebuild epoll set if needed.if (mEpollRebuildRequired) {mEpollRebuildRequired = false;rebuildEpollLocked();goto Done;}for (int i = 0; i < eventCount; i++) {int fd = eventItems[i].data.fd;uint32_t epollEvents = eventItems[i].events;if (fd == mWakeEventFd.get()) {} else {ssize_t requestIndex = mRequests.indexOfKey(fd);if (requestIndex >= 0) {int events = 0;if (epollEvents & EPOLLIN) events |= EVENT_INPUT;if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;if (epollEvents & EPOLLERR) events |= EVENT_ERROR;if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;pushResponse(events, mRequests.valueAt(requestIndex));} else {ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is ""no longer registered.", epollEvents, fd);}}}
Done: ;// Release lock.mLock.unlock();// Invoke all response callbacks.for (size_t i = 0; i < mResponses.size(); i++) {Response& response = mResponses.editItemAt(i);if (response.request.ident == POLL_CALLBACK) {int fd = response.request.fd;int events = response.events;void* data = response.request.data;int callbackResult = response.request.callback->handleEvent(fd, events, data);if (callbackResult == 0) {removeFd(fd, response.request.seq);}response.request.callback.clear();result = POLL_CALLBACK;}}return result;
} 
 当监听到注册的fd发生事件,则先将这些事件封装成Respone数据,然后在pollInner的结束时去调用callback(NativeMessageQueue)的handleEvent方法回调,如果handleEvent的返回值为0,则注销这个监听。
MessageQueue.dispatchEvents
int NativeMessageQueue::handleEvent(int fd, int looperEvents, void* data) {int events = 0;if (looperEvents & Looper::EVENT_INPUT) {events |= CALLBACK_EVENT_INPUT;}if (looperEvents & Looper::EVENT_OUTPUT) {events |= CALLBACK_EVENT_OUTPUT;}if (looperEvents & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP | Looper::EVENT_INVALID)) {events |= CALLBACK_EVENT_ERROR;}int oldWatchedEvents = reinterpret_cast<intptr_t>(data);int newWatchedEvents = mPollEnv->CallIntMethod(mPollObj,gMessageQueueClassInfo.dispatchEvents, fd, events);if (!newWatchedEvents) {return 0; // unregister the fd}if (newWatchedEvents != oldWatchedEvents) {setFileDescriptorEvents(fd, newWatchedEvents);}return 1;
} 
 NativeMessageQueue.handleEvent()方法将Looper传过来的事件类型转换成MessageQueue这边的events,并调用Java层MessageQueue的dispatchEvents()方法来回调用户注册的回调方法,并根据其返回的继续监听的事件类型来进行判断,如果新的监听事件为0,表示不需要继续监听,则将这个监听注销,返回0。如果新的监听事件与旧的监听事件不同,则更新监听事件。
// Called from native code.
@UnsupportedAppUsage
private int dispatchEvents(int fd, int events) {// Get the file descriptor record and any state that might change.final FileDescriptorRecord record;final int oldWatchedEvents;final OnFileDescriptorEventListener listener;final int seq;synchronized (this) {record = mFileDescriptorRecords.get(fd);if (record == null) {return 0; // spurious, no listener registered}oldWatchedEvents = record.mEvents;events &= oldWatchedEvents; // filter events based on current watched setif (events == 0) {return oldWatchedEvents; // spurious, watched events changed}listener = record.mListener;seq = record.mSeq;}// Invoke the listener outside of the lock.int newWatchedEvents = listener.onFileDescriptorEvents(record.mDescriptor, events);if (newWatchedEvents != 0) {newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;}// Update the file descriptor record if the listener changed the set of// events to watch and the listener itself hasn't been updated since.if (newWatchedEvents != oldWatchedEvents) {synchronized (this) {int index = mFileDescriptorRecords.indexOfKey(fd);if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record&& record.mSeq == seq) {record.mEvents = newWatchedEvents;if (newWatchedEvents == 0) {mFileDescriptorRecords.removeAt(index);}}}}// Return the new set of events to watch for native code to take care of.return newWatchedEvents;
} 
 MessageQueue.dispatchEvents的核心就是根据fd找到对应的listener对象,调用其onFileDescriptorEvents()方法去处理这个事件,并根据其返回的继续需要监听的事件做与NativeMessageQueue.handleEvent类似的操作。回顾NetworkStack的FdEventsReader的addOnFileDescriptorEventListener的代码,可以知道,其主要作用就是利用Android的native层的Looper来实现对Linux内核的netlink socket的监听。类似的还有InputFlinger的InputDispatcher的对应用的InputChannel的回调监听。
总结

 以上是Android Message机制个人理解的框图,总结如下:
 1.每个线程Thread最多只有一个Looper和MessageQueue实例,一个进程可以有多个Looper和MessageQueue实例,可以参考SystemServer。
 2.每个Looper和MessageQueue实例是一一对应的,Looper是线程的主体,线程的最终执行代码将是Looper的不断循环执行,MessageQueue是消息的容器,也是Looper种不断执行的指令来源。
 3.MessageQueue中的重要数据元素就是Message,MessageQueue中组织Message的容器使用的是单链表。链表中Message在入链表时会进行排序,其排序时根据处理时间的顺序,也就是说链表头的Message会最先被处理。
 4.Message和Handler的实例在一个线程中并不是唯一的,但两种是互相绑定的,Message中必然会有一个与其相关的Handler实例,这个Handler实例是分发Message的中介,同时也可以是Message的处理句柄,用于处理Message。但Message并不一定要交由Handler来处理,Message可以设置自己的Callback(Runnable),执行Runnable的内容。
 5.Message是实现使用了缓存池的机制,主要是为了减少Java层创建对象的开销。Message是Android java层常用的类型,一个进程运行的过程可能会使用非常多的Message,如果每个Message都重新创建,会加大cpu的开销(创建需要消耗cpu,同样的,销毁执行gc也是需要消耗cpu的)。
 6.MessageQueue.next()方法是一个阻塞的方法,Looper.loop()方法就是通过阻塞来进入休眠,而这个阻塞是MessageQueue的JNI层调用native层Looper实现的,native层Looper使用的是epoll机制进行监听和阻塞。
问题
1.在知乎上看到有人问,Android 中为什么需要Handler?
 我认为Handler的说法并不准确,应该说的是Android为什么需要Message机制,Handler只是Message机制中的处理方式,或者说是处理消息的一种手段的具体实现,而实际上核心的东西是整套机制的协调使用。
 Android中为什么需要Message机制呢?我认为主要是因为Android的设计框架很多都是基于C/S结构的,进程间、进程内线程间,很多都可以看作是C/S的架构,如SystemServer、AndroidO之后的hal层服务以及应用的UI刷新,这些都可以看作是C/S架构。那么Android中进程间的C/S架构的通信机制设计有了Binder(HwBinder等),那么线程间的通信机制呢?因为线程间是处于同一个资源集合中,无需使用Binder这种经过内核态的通信机制,而消息机制就很适合这种场景,其有控制简单,串行(消息都是通过一个线程处理)的特点,十分适合线程间通信的。
 知乎上有人就Android应用的场景展开说明,谈到UI更新的使用,看似十分有理,但这仅仅只是Message机制的一个应用场景,从源码上看,一个进程并不是只能有一个Looper的存在,而是可以有多个Looper的,UI线程都是在主线程种,但是Looper并不需要一定在主线程种,而且较为新的版本种,Message机制并不仅仅可以作为消息传递,还能监听一个文件节点(socket,驱动节点等),站在系统的层面上看,Android系统是一个集中处理数据的大型软件,数据的处理离不开消息的驱动,那么必然需要一种消息机制来进行驱动,消息的机制驱动又可以分别进程间和线程间的。进程间已有binder这一高效的通信机制,那么线程间也必然需要设计一款高效的通信机制,Message机制也就应运而生(其实很多系统都会有类似的机制)。
2.MessageQueue.next()方法中,调用nativePollOnce()的作用是什么?特别是第一次循环时的作用。
nativePollOnce是进入线程阻塞的核心方法,其底层是基于epoll机制。但第一次循环时epoll的timeout为0,表示进行阻塞,只读取事件,我认为作用用二:①清除过时的wake事件;②处理监听的文件节点事件。


















