注:下列源码均基于9.0,可通过下列方式下载本文相关源码到本地:
参考博客:如何下载和阅读Android源码
前言
在上一篇文章Android之Actvitiy启动流程(一)中我们已经分析了根Activity启动时所需的应用进程是如何创建的,并且当前应用进程已经启动了ActivityThread的main方法,所以这篇文章主要围绕下列内容展开来讲解:
- 应用进程绑定到AMS
- AMS发送启动Activity的请求
- ActivityThread的Handler处理启动Activity的请求
一、应用进程绑定到AMS
1. 时序图
2. 详细过程
在前面一篇我们知道当Zygote进程孵化出应用进程后会执行ActivityThread的main方法,所以我们先看看main方法里的代码。
frameworks/base/core/java/android/app/ActivityThread.java
1 | public static void main(String[] args) { |
在这里我们就不再详细分析prepareMainLooper和loop方法,其主要功能就是准备好主线程的Looper以及消息队列,最后再开启主线程的消息循环。如果不懂的可以看看前面的博客Handler机制中对这两个方法的分析,在这里我们将重点分析attach这个方法。
frameworks/base/core/java/android/app/ActivityThread.java
1 | private void attach(boolean system, long startSeq) { |
可以看到由于在ActivityThread的attach中我们传入的是false,故在attach方法中将执行!system里的代码,通过调用AMS的attachApplication来将ActivityThread中的内部类ApplicationThread对象绑定至AMS,这样AMS就可以通过这个代理对象 来控制应用进程。接着为这个进程添加垃圾回收观察者,每当系统触发垃圾回收的时候就在run方法中计算应用使用了多大的内存,如果超过总量的3/4就尝试释放内存。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
1 | public final void attachApplication(IApplicationThread thread, long startSeq) { |
在AMS的attachApplication方法中调用了attachApplicationLocked进行绑定,从上面代码可以发现attachApplicationLocked中有两个重要的方法:thread.bindApplication和mStackSupervisor.attachApplicationLocked(app)。thread.bindApplication中的thread其实就是ActivityThread里ApplicationThread对象在AMS的代理对象,故此方法将最终调用ApplicationThread的bindApplication方法。而mStackSupervisor.attachApplicationLocked(app)主要是AMS启动Activity的作用(在下列AMS发送启动Activity的请求会分析到)。在这里我们先看看ApplicationThread的bindApplication方法。
frameworks/base/core/java/android/app/ActivityThread.ApplicationThread
1 | public final void bindApplication(String processName, ApplicationInfo appInfo, |
可以发现上面其实就是Handler机制的应用,mH其实就是H类型的,所以bindApplication主要就是向ActivityThread的Handler,即H发送绑定的消息。
frameworks/base/core/java/android/app/ActivityThread.H
1 | //线程所需要的Handler,内部定义了一组消息类型,主要包括四大组件的启动和停止过程 |
这个H其实就是当前线程,也可以说是主线程ActivityThread的Handler,内部定义了一组消息类型,包括了四大组件的启动和停止过程。通过Handler机制我们知道在H的handleMessage中会处理发送给H的消息,在这里将调用handleBindApplication方法。
frameworks/base/core/java/android/app/ActivityThread
1 |
|
二、AMS发送启动Activity的请求
应用进程绑定后,随之就得启动Activity,那么得向谁发送启动Activity得到请求呢?显而易见,当然是向主线程即ActivityThread发送启动Activity的请求。下面就让我们一探究竟!
1. 时序图
2. 详细过程
现在当前进程已经绑定到了AMS,绑定后呢?回忆一下,上面对AMS的attachApplicationLocked方法分析时,重点提到了两个方法,其中ApplicationThread的bindApplication方法我们分析应用进程是如何绑定到AMS的,没错!另外一个方法mStackSupervisor.attachApplicationLocked(app)就是用来启动Activity的,现在让我们来看看。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
1 | boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { |
attachApplicationLocked会调用realStartActivityLocked方法,如下。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
1 | final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, |
在realStartActivityLocked方法中为ClientTransaction对象添加LaunchActivityItem的callback,然后设置当前的生命周期状态,由于我们是根Activity的启动,很显然这里的生命周期为ResumeActivityItem,最后调用ClientLifecycleManager.scheduleTransaction方法执行。我们继续追踪下去!
frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java
1 | void scheduleTransaction(ClientTransaction transaction) throws RemoteException { |
从上面代码中可以看出,由于transaction为ClientTransaction类型,故接下去将执行ClientTransaction的schedule方法
frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java
1 | public void schedule() throws RemoteException { |
mClient是IApplicationThread类型,通过名字和阅读源码我们可以知道ApplicationThread会实现该类型,所以这里调用的应该是ApplicationThread的scheduleTransaction方法,我们知道ApplicationThread是ActivityThread的内部类,所以通过阅读ActivityThread源码你会发现在这个类中并没有实现scheduleTransaction这个方法,难道分析错了????
聪明的你应该想到了,既然在当前类找不到这个方法,只能去找父类寻求帮助了,果然姜还是老的辣,在ActivityThread的父类ClientTransactionHandler中我们找到了这个scheduleTransaction方法。如下
frameworks\base\core\java\android\app\ClientTransactionHandler.java
1 | void scheduleTransaction(ClientTransaction transaction) { |
看到这是不是突然觉得很熟悉,不急,我们一步一步来分析!在这个方法中会调用sendMessage方法,而在ClientTransactionHandler类中该sendMessage方法为抽象方法,其具体实现在子类ActivityThread中,如下
frameworks/base/services/core/java/com/android/server/am/ActivityThread.java
1 | void sendMessage(int what, Object obj) { |
上面的代码很容易理解,在ActivityThread的sendMessage中会把启动Activity的消息发送给mH,而mH为H类型,其实就是ActivityThread的Handler。到这里AMS就将启动Activity的请求发送给了ActivityThread的Handler。
三、ActivityThread的Handler处理启动Activity的请求
1. 时序图
2. 详细过程
既然发送了启动Activity的消息,那么就得ActivityThread当然得处理这个消息,我们知道Handler机制,如果是通过sendMessage的方法发送消息的话,应该是在Handler的handleMessage处理消息,在这里也同样如此,ActivityThread的Handler就是H,让我们来看看H的handleMessage,看看是否能找到EXECUTE_TRANSACTION消息的处理.
frameworks/base/core/java/android/app/ActivityThread.H
1 | public void handleMessage(Message msg) { |
果真如此,我们H接受到AMS发来的EXECUTE_TRANSACTION消息后,将调用TransactionExecutor.execute方法来切换Activity状态。
frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java
1 | public void execute(ClientTransaction transaction) { |
在execute方法中重点关注两个方法:executeCallbacks,由于我们现在分析的是根Activity的启动流程,从上面也可以知道此时的callback是不为null的,所以会执行executeCallbacks,最终会执行Activity的onCreate方法.此时根Activity就已经启动成功了。executeLifecycleState方法是用来改变活动的生命周期状态的,如果是根Activity的启动,最终将会执行onStart和onResume方法。下面来分析这两个方法
2.1 执行onCreate方法
来看看executeCallbacks这个方法。
frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java
1 |
|
从上面的分析我们知道根Activity启动时这个callback的ClientTransactionItem为LaunchActivityItem,所以会执行LaunchActivityItem的execute方法。
frameworks\base\core\java\android\app\servertransaction\LaunchActivityItem.java
1 |
|
上面的client为ActivityThread,所以会继续调用ActivityThread的handleLaunchActivity方法,如下。
1 | public Activity handleLaunchActivity(ActivityClientRecord r, |
在上述方法中将调用performLaunchActivity来启动活动,如下
1 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
该方法代码很多,要干的事情也挺多的,并且都很重要,通过注释应该可以知道这个方法的任务,当干完所有事后得将当前的生命周期设置为ON_CREATE。我们重点关注启动活动的代码mInstrumentation.callActivityOnCreate,可以知道在这里将会调用Instrumentation的callActivityOnCreate来启动活动。
frameworks\base\core\java\android\app\Instrumentation.java
1 | public void callActivityOnCreate(Activity activity, Bundle icicle) { |
而callActivityOnCreate将调用Activity的performCreate,如下
frameworks\base\core\java\android\app\Activity.java
1 | final void performCreate(Bundle icicle) { |
看得到这眼泪是否哗啦啦啦的流下了,终于看到熟悉的东西了,在Activity的performCreate中将执行onCreate,也就是我们在开发中所熟悉的onCreate,“终于等到你,还好我们没放弃”,讲到这,根Activity就已经启动了,我们的万里长征也应该结束了,但是身为万里长征的首席指挥官,总不能一结束就撒手不管吧。所以让我们继续来看看结束后的维护工作。
2.2 执行onStart方法
从上面分析中我们知道onCreate已经被调用,且生命周期的状态是ON_CREATE,故executeCallbacks已经执行完毕,所以开始执行executeLifecycleState方法。如下
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
1 | private void executeLifecycleState(ClientTransaction transaction) { |
在executeLifecycleState方法中,会先执行cycleToPath,从上面的分析我们已经知道当根Activity启动时,此时的lifecycleItem为ResumeActivityItem,故调用lifecycleItem.getTargetState时将得到ON_RESUME状态,让我们来瞧瞧cycleToPath方法。
1 | private void cycleToPath(ActivityClientRecord r, int finish, |
由于onCreate方法已经执行,所以start为ON_CREATE,而finish为上面传递的ON_RESUME,excludeLastState是否移除最后的状态为true。让我们来看看getLifecyclePath这个方法
frameworks/base/core/java/android/app/servertransaction/TransactionExecutorHelper.java
1 | public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) { |
在getLifecyclePath这个方法我们知道start为ON_CREATE,finish为ON_RESUME,那么如何知道start和finish的大小关系呢?在ActivityLifecycleItem中我们可以发现这些状态的定义,从定义中可以发现finish>=start,所以我们只关注这部分的逻辑处理,可以发现ON_CREATE和ON_RESUME中间还有ON_START这个状态,所以mLifecycleSequence将添加ON_START和ON_RESUME状态,但是又因为excludeLastState为true,所以最后会移除掉ON_RESUME状态,故返回的类型只包含ON_START状态。故cycleToPath方法中的path中将只包含ON_START状态,然后继续执行performLifecycleSequence方法。
1 | private void performLifecycleSequence(ActivityClientRecord r, IntArray path) { |
因为path只包含ON_START状态,所以只执行ActivityThread的handleStartActivity方法。
frameworks/base/core/java/android/app/ActivityThread.java
1 | public void handleStartActivity(ActivityClientRecord r, |
frameworks/base/core/java/android/app/Activity.java
1 | final void performStart(String reason) { |
frameworks/base/core/java/android/app/Instrumentation.java
1 | public void callActivityOnStart(Activity activity) { |
从上面可以发现ActivityThread.handleStartActivity经过多次跳转最终会执行activity.onStart方法,至此cycleToPath方法执行完毕。
2.3 执行onResume方法
让我们回到executeLifecycleState这个方法,执行完cycleToPath方法后将执行lifecycleItem.execute,即ResumeActivityItem的execute方法。
frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
1 |
|
frameworks/base/core/java/android/app/ActivityThread.java
1 |
|
frameworks/base/core/java/android/app/Activity.java
1 | final void performResume(boolean followedByPause, String reason) { |
frameworks/base/core/java/android/app/Instrumentation.java
1 | public void callActivityOnResume(Activity activity) { |
可以发现其实执行onCreate,onStart,onResume的流程大致上是类似的,通过多次调用最终将会调用Activity的onResume方法,至此Activity真正启动完毕!
总结
理解根Activity的启动流程至关重要,在此次分析根Activity的启动流程中对Activity的生命周期也有了更深的了解,由于在分析过程中是基于Android9.0的,与之前的版本有些改动,有时候会陷入源码的沼泽中,越挣扎陷的越深。所以我觉得我们应该借助源码来把握整体流程,但又不能纠结于读懂源码中的任何代码,这是不太现实的。
两篇文章结合起来,我们可以得知Activity的启动的整体流程:
- Launcher进程请求AMS
- AMS发送创建应用进程请求
- Zygote进程接受请求并孵化应用进程
- 应用进程启动ActivityThread
- 应用进程绑定到AMS
- AMS发送启动Activity的请求
- ActivityThread的Handler处理启动Activity的请求
参考博客: