学习下startActivity的具体流程,版本为Android-28
在手机桌面上点击某一个icon之后,实际上最终就是通过startActivity去打开某一个Activity页面。
在Android中一个App就相当于一个进程, 所以startActivity操作中还需要判断 , 目标Activity的进程是否已经创建 ,如果没有,则在显示之前还需要将进程Process提前创建出来。
假设是从ActivityA跳到另一个App中的ActivityB,过程如下:
整个startActivity的流程分为3大部分 ,也涉及3个进程之间的交互 :
这过程并不复杂,用一张图表示:
看下源码都做哪些操作:
最终调用startActivityForResult方法,传入的-1表示不需要获取startActivity的结果。
具体代码如下:
startActivityForResult也很简单,调用Instrumentation.execStartActivity方法,剩下的交给Instrumentation类去处理
解释:
方法如下:
在Instrumentation中,会通过ActivityManager.getServer获取AMS的实例,然后通过调用其startActivity方法,实际上这里就是通过AIDL来调用AMS的startActivity方法,至此, startActivity的工作重心就从进程A转移到了系统进程AMS中 !
接下来看下AMS中是如何一步步执行到B进程的
提前了解下:刚才在看Instrumentation时,提到一个ApplicationThread类,这个类是负责进程间通信的,这里AMS最终其实就是调用了B进程中的一个ApplicationThread引用,从而间接地通知B进程进行相应的操作
AMS –> ApplicationThread 流程,里面就干了2件事:
接下来就从AMS的startActivity方法开始看起:
从上图看出,经过多个方法调用,最终通过obtainStarter方法获取了ActivityStarter类型的对象,然后调用其execute方法。在execute方法中会再次调用其内部的startActivityMayWait方法
ActivityStarter这个类看名字就知道它专门负责一个Activity的启动操作。它的主要作用包括解析Intent,创建ActivityRecord,如果有可能还要创建TaskRecord。startActivityMayWait方法的部分实现如下:
从上图可以看出获取目标Activity信息的操作由mSupervisor来实现,它是ActivityStackSupervisor类型,从名字可以看出它是主要负责Activity所处栈的管理类 。
上图中resolveIntent中实际上是调用系统PackageManagerService来获取最佳Activity。有时我们通过隐式Intent启动Activity时,系统可能存在多个Activity可以处理Intent,此时会弹出一个选择框让用户选择具体打开哪个Activity,就是此处的逻辑处理结果。
在startActivityMayWait方法中调用了一个重载的startActivity方法,而最终会调用ActivityStarter中的startActivityUnchecked方法来获取启动Activity的结果 。
解释:
这个方法主要是计算启动Activity的Flag,不同的Flag决定了启动Activity最终会被放置到哪一个Task集合中
方法中会调用insertTaskTop方法尝试将Task和Activity入栈。如果Activity是以newTask的模式启动或TASK堆栈中不存在该Task id,则Task会重新入栈,并且放在栈的顶部。需要注意的是:Task先入栈,之后才是Activity入栈,他们是包含关系
这里了解下Stack,Task,Activity的关系,:它们都是在AMS内部维护的数据结构,关系如下:
经过一系列调用,最终又回到了ActivityStackSupervisor中的startSpecificActivityLocked方法
解释:
不管是目标进程已经存在还是新建目标进程,最终都会调用图中红线标记的realStartActivityLocked方法来执行启动Activity的操作
这个方法在Android-27和28版本的区别很大,从28开始Activity的启动交给了事务(Transaction)来完成
Activity 启动事务的执行是由ClientLifecycleManager来完成的,具体如下:
可以看出实际上是调用了启动事务ClientTransaction的schedule方法,而这个transaction实际上是在创建ClientTransaction时传入的app.thread对象,也就是ApplicationThread对象,如下:
解释:
到此为止,startActivity操作就从AMS转移到另一个进程B中的ApplicationThread中,剩下的就是AMS通过进程间通信机制通知ApplicationThread执行Activity-B的生命周期方法。
刚才已经分析了AMS将启动Activity的任务作为一个事务ClientTransaction去完成,在ClientLifecycleManager中会调用ClientTransaction的schedule()方法,如下:
而mClient是一个IApplicationThread接口类型,具体实现是ActivityThread的内部类ApplicationThread。因此后续执行Activity生命周期的过程都是由ApplicationThread指导完成的,scheduleTransaction方法如下:
可以看出,这里还是调用了ActivityThread的scheduleTransaction方法。但是这个方法实际上是在ActivityThread的父类ClientTransactionHandler中实现,具体如下:
调用sendMessage方法,向Handler中发送了一个EXECUTE_TRANSACTION的消息,并且Message中的obj就是启动Activity的事务对象。而这个Handler的具体实现是ActivityThread中的mH对象。具体如下:
最终调用了事务的execute方法,execute方法如下:
在executeCallbacl方法中,会遍历事务中的callback并执行execute方法,这些callbacks是何时被添加的呢?
看一下上面ClientTransaction创建的代码:
在创建ClientTransaction时,通过addCallback方法传入了Callback参数,从图中可以看出其实是一个LauncherActivityItem类型的对象。
终于跟到了Activity生命周期相关的方法了,图中client是ClientTransactionHandler类型,实际实现类就是ActivityThread。因此最终方法又回到了ActivityThread。
这是一个比较重要的方法,Activity的生命周期方法就是在这个方法中有序执行,具体如下:
解释:
至此,目标Activity已经被成功创建并执行生命周期方法
主要学习了解了Activity的启动在源码中的实现流程。这一过程主要涉及3个进程间的通信过程: