<
startActivity启动过程分析
>
上一篇

探索Window、Activity、View三者关系
下一篇

Android Bitmap学习

学习下startActivity的具体流程,版本为Android-28

startActivity启动过程分析

在手机桌面上点击某一个icon之后,实际上最终就是通过startActivity去打开某一个Activity页面。

在Android中一个App就相当于一个进程, 所以startActivity操作中还需要判断目标Activity的进程是否已经创建 ,如果没有,则在显示之前还需要将进程Process提前创建出来。

假设是从ActivityA跳到另一个App中的ActivityB,过程如下:

1

整个startActivity的流程分为3大部分 ,也涉及3个进程之间的交互

  1. ActivityA -> ActivityManagerService(简称AMS)
  2. ActivityManagerService -> ApplicationThread
  3. ApplicationThread -> Activity

一、ActivityA -> ActivityManagerService

这过程并不复杂,用一张图表示:

2

看下源码都做哪些操作:

1.Activity的startActivity

3

最终调用startActivityForResult方法,传入的-1表示不需要获取startActivity的结果。

2.Activity的startActivityForResult

具体代码如下:

4

startActivityForResult也很简单,调用Instrumentation.execStartActivity方法,剩下的交给Instrumentation类去处理

解释:

3.Instrumentation的execStartActivity

方法如下:

5

在Instrumentation中,会通过ActivityManager.getServer获取AMS的实例,然后通过调用其startActivity方法,实际上这里就是通过AIDL来调用AMS的startActivity方法,至此, startActivity的工作重心就从进程A转移到了系统进程AMS中

二、ActivityManagerService -> ApplicationThread

接下来看下AMS中是如何一步步执行到B进程的

提前了解下:刚才在看Instrumentation时,提到一个ApplicationThread类,这个类是负责进程间通信的,这里AMS最终其实就是调用了B进程中的一个ApplicationThread引用,从而间接地通知B进程进行相应的操作

AMS –> ApplicationThread 流程,里面就干了2件事:

  1. 综合处理launchMode和Intent中的Flag标志位,并根据结果生成一个目标ActivityB的对象(ActivityRecord)
  2. 判断是否需要为目标ActivityB创建一个新的进程(ProcessRecord),新的任务栈(TaskRecord)

接下来就从AMS的startActivity方法开始看起:

1.AMS的startActivity

6

从上图看出,经过多个方法调用,最终通过obtainStarter方法获取了ActivityStarter类型的对象,然后调用其execute方法。在execute方法中会再次调用其内部的startActivityMayWait方法

2.ActivityStarter的startActivityMayWait

ActivityStarter这个类看名字就知道它专门负责一个Activity的启动操作。它的主要作用包括解析Intent,创建ActivityRecord,如果有可能还要创建TaskRecord。startActivityMayWait方法的部分实现如下:

7

从上图可以看出获取目标Activity信息的操作由mSupervisor来实现,它是ActivityStackSupervisor类型,从名字可以看出它是主要负责Activity所处栈的管理类

上图中resolveIntent中实际上是调用系统PackageManagerService来获取最佳Activity。有时我们通过隐式Intent启动Activity时,系统可能存在多个Activity可以处理Intent,此时会弹出一个选择框让用户选择具体打开哪个Activity,就是此处的逻辑处理结果。

在startActivityMayWait方法中调用了一个重载的startActivity方法,而最终会调用ActivityStarter中的startActivityUnchecked方法来获取启动Activity的结果

3.ActivityStarter的startActivityUnchecked

8

解释:

a.computeLaunchingTaskFlags具体

9

这个方法主要是计算启动Activity的Flag,不同的Flag决定了启动Activity最终会被放置到哪一个Task集合中

4.ActivityStackSupervisor的startActivityLocked

10

方法中会调用insertTaskTop方法尝试将Task和Activity入栈。如果Activity是以newTask的模式启动或TASK堆栈中不存在该Task id,则Task会重新入栈,并且放在栈的顶部。需要注意的是:Task先入栈,之后才是Activity入栈,他们是包含关系

这里了解下Stack,Task,Activity的关系,:它们都是在AMS内部维护的数据结构,关系如下:

11

5.ActivityStack的resumeFocusedStackTopActivityLocked

12

经过一系列调用,最终又回到了ActivityStackSupervisor中的startSpecificActivityLocked方法

a.ActivityStackSupervisor的startSpecificActivityLocked

13

解释:

不管是目标进程已经存在还是新建目标进程,最终都会调用图中红线标记的realStartActivityLocked方法来执行启动Activity的操作

6.ActivityStackSupervisor的realStartActivityLocked

14

这个方法在Android-27和28版本的区别很大,从28开始Activity的启动交给了事务(Transaction)来完成

Activity 启动事务的执行是由ClientLifecycleManager来完成的,具体如下:

15

可以看出实际上是调用了启动事务ClientTransaction的schedule方法,而这个transaction实际上是在创建ClientTransaction时传入的app.thread对象,也就是ApplicationThread对象,如下:

16

解释:

到此为止,startActivity操作就从AMS转移到另一个进程B中的ApplicationThread中,剩下的就是AMS通过进程间通信机制通知ApplicationThread执行Activity-B的生命周期方法。

三、ApplicationThread -> Activity

刚才已经分析了AMS将启动Activity的任务作为一个事务ClientTransaction去完成,在ClientLifecycleManager中会调用ClientTransaction的schedule()方法,如下:

17

而mClient是一个IApplicationThread接口类型,具体实现是ActivityThread的内部类ApplicationThread。因此后续执行Activity生命周期的过程都是由ApplicationThread指导完成的,scheduleTransaction方法如下:

18

可以看出,这里还是调用了ActivityThread的scheduleTransaction方法。但是这个方法实际上是在ActivityThread的父类ClientTransactionHandler中实现,具体如下:

19

调用sendMessage方法,向Handler中发送了一个EXECUTE_TRANSACTION的消息,并且Message中的obj就是启动Activity的事务对象。而这个Handler的具体实现是ActivityThread中的mH对象。具体如下:

20

最终调用了事务的execute方法,execute方法如下:

21

在executeCallbacl方法中,会遍历事务中的callback并执行execute方法,这些callbacks是何时被添加的呢?

看一下上面ClientTransaction创建的代码:

22

在创建ClientTransaction时,通过addCallback方法传入了Callback参数,从图中可以看出其实是一个LauncherActivityItem类型的对象。

1.LauncherActivityItem的execute()

23

终于跟到了Activity生命周期相关的方法了,图中client是ClientTransactionHandler类型,实际实现类就是ActivityThread。因此最终方法又回到了ActivityThread。

2.ActivityThread的handleLaunchActivity

这是一个比较重要的方法,Activity的生命周期方法就是在这个方法中有序执行,具体如下:

24

解释:

至此,目标Activity已经被成功创建并执行生命周期方法

总结

主要学习了解了Activity的启动在源码中的实现流程。这一过程主要涉及3个进程间的通信过程:

Top
Foot