几个月前用安卓写代码时总结的一些东西,现在发出来充充数,以后要多写写博客了。
概述
本文主要是针对Android消息分发过程中的几个要点:
- 消息队列messageQueue构造
- 主线程Looper的Loop过程
- Activity怎么启动主Loop过程
messageQueue.next()
函数的具体过程- UI分层结构,不同UI层次间的关系消息分发的层次
ActivityThread的启动过程
一个新的ActivityThread的创立,标志着一个新的应用被打开,而在安卓系统中,所有的应用都是以Activity的形式表示,桌面是一个Activity,导航栏是一个Activity,新打开的应用也是一个Activity。
每个应用都有一个自己的进程空间,应用进程通过vegote进行fork创建并启动我们指定的MainActivity,然后应用进程的主线程开始执行自己的main函数,初始化looper、messageQueue,并绑定Handler,然后进入loop循环开始等待消息的传入并处理。
根据不同的消息,主线程可能会通过Handler的不同处理,通知不同的Activity进入不同的状态,或者终结一个Activity的生命周期,或者仅仅只是将点击事件分发给不同的view让其自行执行回调。
至少从主线程循环的角度看来,安卓应用是一种消息驱动的应用模型。
消息传递结构
MessageQueue 消息队列
其中Message mMessages记录的就是一条消息链表,而Looper的loop函数实质就是从MessageQueue中取出消息然后进行处理的过程。
另外在MessageQueue中还有几个native函数,这就说明MessageQueue会通过JNI技术调用到底层代码。mMessages域记录着消息队列中所有Java层的实质消息。当然,记录的只是Java层的消息,不包括C++层的。
MessageQueue的示意图如下:
MessageQueue.next()——nativePollOnce()函数
MessageQueue.next()函数中中调用的nativePollOnce()调用到了C++层,这个函数起到了阻塞线程的作用,保证消息循环不会在无消息处理时一直在那里“傻转”,而通过native层的Looper实现可以很好的看到nativePollOnce函数是如何被阻塞,又是在何时被何种方式唤醒的。
C++层的Looper代码:
Looper::Looper(bool allowNonCallbacks) :mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),mPolling(false), mEpollFd(-1), mEpollRebuildRequired(