一、Activity启动过程
应用冷启动过程:
- Launcher进程通过Binder机制通知AMS创建应用
- AMS判断当前应用是否启动,没有启动通过Socket通讯通知Zygote进程fork应用进程
- AMS通过Binder机制请求ApplicationThread创建并启动根Activity
- ApplicationThread通过Handle机制通知主线程ActivityThread,最终调用到根Activity的onCreat方法
应用热启动过程:
- Launcher进程通过Socket通讯通知AMS创建应用
- AMS判断当前应用是否启动,已经启动则无需再次创建App进程
- AMS通过Binder机制请求ApplicationThread创建并启动根Activity
- ApplicationThread通过Handle机制通知主线程ActivityThread,最终调用到根Activity的onCreat方法
二、Service的启动过程
Service的启动流程和Activity类似,以下是Service的大致启动流程
三、Service的绑定流程
Serice的绑定流程比startService的流程稍微要复杂一点,大概的时序图可以分为下面3个部分
1、Client发起bindService调起AMS的过程
2、AMS通知App进程发起绑定Service的过程
3、Service实际绑定的过程
四、广播的注册、发送和接收
1、广播的注册过程
- 动态注册的过程是从ContextWrapper#registerReceiver()开始的. 和Activity或者Service一样. ContextWrapper并没有做实际的工作, 而是将注册的过程直接交给了ContextImpl来完成。
- ContextImpl#registerReceiver()方法调用了本类的registerReceiverInternal()方法。
- 系统首先从mPackageInfo获取到IIntentReceiver对象, 然后再采用跨进程的方式向AMS发送广播注册的请求. 之所以采用IIntentReceiver而不是直接采用BroadcastReceiver, 这是因为上述注册过程中是一个进程间通信的过程. 而BroadcastReceiver作为Android中的一个组件是不能直接跨进程传递的. 所有需要通过IIntentReceiver来中转一下。
- IIntentReceiver作为一个Binder接口, 它的具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver, ReceiverDispatcher的内部同时保存了BroadcastReceiver和InnerReceiver, 这样当接收到广播的时候, ReceiverDispatcher可以很方便的调用BroadcastReceiver#onReceive()方法. 这里和Service很像有同样的类, 并且内部类中同样也是一个Binder接口。
- 由于注册广播真正实现过程是在AMS中, 因此跟进AMS中, 首先看registerReceiver()方法, 这里只关心里面的核心部分. 这段代码最终会把远程的InnerReceiver对象以及IntentFilter对象存储起来, 这样整个广播的注册就完成了。
2、广播的发送和接收
广播的发送有几种:普通广播、有序广播和粘性广播,他们的发送/接收流程是类似的,因此只分析普通广播的实现。
1.广播的发送和接收, 本质就是一个过程的两个阶段. 广播的发送仍然开始于ContextImpl#sendBroadcase()方法, 之所以不是Context, 那是因为Context#sendBroad()是一个抽象方法. 和广播的注册过程一样, ContextWrapper#sendBroadcast()仍然什么都不做, 只是把事情交给了ContextImpl去处理。
2.ContextImpl里面也几乎什么都没有做, 内部直接向AMS发起了一个异步请求用于发送广播。
3.调用AMS#broadcastIntent()方法,继续调用broadcastIntentLocked()方法。
4.在broadcastIntentLocked()内部, 会根据intent-filter查找出匹配的广播接收者并经过一系列的条件过滤. 最终会将满足条件的广播接收者添加到BroadcastQueue中, 接着BroadcastQueue就会将广播发送给相应广播接收者。
5.BroadcastQueue#scheduleBroadcastsLocked()方法内并没有立即发送广播, 而是发送了一个BROADCAST_INTENT_MSG类型的消息, BroadcastQueue收到消息后会调用processNextBroadcast()方法。
6.无序广播存储在mParallelBroadcasts中, 系统会遍历这个集合并将其中的广播发送给他们所有的接收者, 具体的发送过程是通过deliverToRegisteredReceiverLocked()方法实现。deliverToRegisteredReceiverLocked()负责将一个广播发送给一个特定的接收者, 它的内部调用了performReceiverLocked方法来完成具体发送过程。
7.performReceiverLocked()方法调用的ApplicationThread#scheduleRegisteredReceiver()实现比较简单, 它通过InnerReceiver来实现广播的接收。
8.scheduleRegisteredReceiver()方法中,receiver.performReceive()中的receiver对应着IIntentReceiver类型的接口. 而具体的实现就是ReceiverDispatcher#InnerReceiver. 这两个嵌套的内部类是所属在LoadedApk中的。
9.又调用了LoadedApk$ReceiverDispatcher#performReceive()的方法.在performReceiver()这个方法中, 会创建一个Args对象并通过mActivityThread的post方法执行args中的逻辑. 而这些类的本质关系就是:
- Args: 实现类Runnable。
- mActivityThread: 是一个Handler, 就是ActivityThread中的mH. mH就是ActivityThread$H. 这个内部类H以前说过。
10.实现Runnable接口的Args中BroadcastReceiver#onReceive()方法被执行了, 也就是说应用已经接收到了广播, 同时onReceive()方法是在广播接收者的主线程中被调用的。
五、ContentProvider的启动过程
ContentProvider的启动过程和其他3大组件基本类似,都是通过AMS实现进程间的数据共享,这里主要列举一下ContentResolver里的query方法到AMS的过程和AMS启动ContentProvider的过程