本文主要学习并了解Application的Activity启动流程。
这边先分析一下Launcher是如何启动进程的Acitivity流程。从Launcher启动Acitivity的时候,它是把启动任务丢给instrumentation模块去协助完成,由它进一步调用AMS的startActivity()方法
去启动(Binder跨 进程调用),从调用启动startActivity()开始到Activity启动调用onResume(),大约经历非常多个步骤。
过一下启动Activity的大致分析(假设以ActivityA->ActivityB):
- 1.Activity参数解析 (存在于AMS:systemserver进程)
Activity的启动流程是使用Intent的方式,作为参数传入,因此启动Activity的初始重要步骤是需要解析Activity需要的启动参数。
- 2.Activity的管理(存在于AMS:systemserver进程)
在Framework中Activity是由谁管理的?其实是由activityStack进行管理,但在AMS服务中,它对应的代表是ActivityRecord,也就是说在ActivityStack中管理的对象的ActivityRecord,所以启动activity时,需要借助activityStack,由它去管理与启动activity.比如activityA->activityB时,B启动时,一定会影响A的生命周期,这些都需要由ActivityStack去管理。
- 3 进程间通信
前面2小点是在AMS中处理,它属于SystemServer进程,但是对于activity的很多工作,需要由Application进程去操作 ,这就涉及到了IBinder进程间通信
- 4.application的处理
在AMS中,将对应的Application的生命周期的所有事务都会在activityStackSupervisor类中被封装成一个clientTransaction的触发事件,它包含了操作Application activity的一系列的命令,然后借助Binder,将clientTransaction传递给Application,Application拿到命令后,去执行Application Activity的生命周期。
- 5 Activity-A生命周期stop的执行
- 下面先来学习Activity参数的解析(即上面说的第一阶段:Activity参数解析)
分析过程依据下面的流程进行,
图1
instrumentation跨进程调用ATMS的startActivity(), ATMS会调用自己的startActivityAsUser(),这是按用户的需求启动activity,这个接口里会去解析
用户的参数需求,
ATMS->startActivityAsUser():
//1 理解ActivityStarter类:这是一个重要的类,专门负责activity的启动时的参数解析
//2 理解ActivityStartController类:负责生产ActivityStarter对象,由controller创建
//3 ActivityStartController在ATMS中的initialize()中被创建:mActivityStartController = new ActivityStartController(this);
ATMS里只有一个startController对象,利用它来辅助ATMS来管理starter对象,每个activity对应一个activityStart.
-->getActivityStartController().obtainstarter(intent, "startActivityAsUser")....()..().execute(); //会初始化Request内部类对象
-->ActivityStartController.java->obtainStarter():
-->return mFactory.obtain().setIntent().setReason();
-->ActivityStarter.java->execute():
-->//插入补充内容: ActivityStarter内部有一个内部类Request:由上面设置,存放activity启动过程中的交互性参数。
//如A->B,需要记录A作为caller,caller是IAPPlicationThread对象,是谁启动了B,这个是要记录的。
//这里面保存着启动actity启动所需要的各类参数配置,非常重要。
executeRequest(mRequest); //利用Request配置好的参数去执行。
-->在里面开始解读Request中的各类参数,并进行一系列的参数判断,然后会调用下面这个关键函数
//Activity在AMS里的存在代表是ActivityRecord,它里面包含着activity的所有属性
final ActivityRecord r = new ActivityRecord();//创建要启动的目标activityRecord对象(即ActivityB),存放到传入数组0索引上
mController.doPendingActivityLaunches(false);//启动那些需要启动,但是一直没来得及启动的Activitys.
-->starter.startResolvedActivity();
-->startActivityUnchecked(); //启动等待的activity
...
startActivityUnchecked();//启动最后需要启动的activity,也就是当前Activity.
--> startActivityInner(); //进一步深入分析,可以感受到starter的价值。
-->setInitialState();//初始化配置,mStartActivity,mLaunchMode等
computerLauncherTaskFlags();//计算要启动的activity flag标志,也就是计算启动模式。
computerSourceStack();//计算源Activity所在的栈。
mIntent.setFlags(mLaunchFlags);//LaunchFlags设置给Intent,也就是设置启动模式。
//...这里有一个细节,如果是Launcher启动activity时,需要能让用户感知已经在启动,所以在这加了黑白屏操作
//如上图所示。
mTargetStack.startActivityLocked(mStartActivity,...); //开始启动
//需要注意,此时我们要启动的Activity对应的Application进程并未启动,但Activity必须依附到进程上。
//RootWindowContainer:窗口容器:定义了windows的存储的层次结构,设备上所有的窗口(window),显示(Disply)都是由它管理的,
//每个activity均对应一个windows,每个windows的显示、隐藏与activity的生命周期有关,
//所以启动activity时走到了RootWindowContainer这个类里面
mRootWindowContainer.resumeFocusedStacksTopActivities();
-->RootWindowContainer.java:会恢复对应任务栈顶部的Activity.即将处于栈顶的activity进行恢复,
//在启动activity时,就是往这个栈的栈顶上去添加一个新的activity,这边涉及到activity的显示过程。
focusedStack.resumeTopActivityUncheckedLocked(); //走到这步就意味着走到了前面文章刚开始说的第2阶段。
- 下面开始分析第二阶段的工作任务:整体 流程如下图所示
图2.
前面说过,解读参数的过程中会创建ActivityRecord,最后会走到RootWindowContainer容器类,由它去调用resumeTopActivityUncheckedLocked,进入ActivityStack
类的中去处理,这个是第二阶段,下面来分析下ActivityStack如何去管理 ActivityRecord,管理它的启动的。
ActivityStack.java->resumeTopActivityUncheckedLocked():
-->resumeTopActivityInnerLocked(): //管理栈的接口
-->if(!hasRunningActivity)://不存在 正在运行的activity的时候
return resumeNextFocusableActivityWhenStackIsEmpty();
//当A->B时,A要先进入onPause
if(mResumedActivity != NULL){
pausing |= startPausingLocked();//停止当前Activity的生命周期
-->ActivityStack.java:startPausingLocked()
mAtmService.getLifeCycleManager().scheduleTransaction(.., PauseActivityItem.obtain() ); //通过它来停止
}
//next就是要启动的这个ActivityRecord,它是一个全新的ActivityRecord,所以这里的返回值是false.
ActivityRecord next = TopRunningActivity(true);
if(next.attachedToProcess()) //需要与Application进程关联,但 由于它是刚创建 ,application进程创建消息还未发送,所以这边是false
-->return hasProcess() && app.hasThread();
-->return app != NULL; //此时app==NULL
else{ //所以会走这边,这里要注意一下
//启动指定的Activity. 从这开始ActivityStackSupervisor类开始登场。它用于管理ActivityStack的类,是ActivityStack的主管。
//ActivityStackSupervisor类需要封装clientTransaction事件-->传给 app进程
mStackSupervisor.startSpecificActivity(next, true,true);
-->//这里进入了创建app进程的起点了。可以参考前面的这篇文章《android framework之Applicataion启动流程分析》
if(wpc != null && wpc.hasThread() ) { //进程如果已经创建的话,直接启动Activity.我们现在看这边
realStartActivityLocked(r,wpc, andResume=true, checkConfig);
--> //创建ClientTransaction对象,这个类extends Parcelable:因为它代表activity生命周期要执行的事件,
//这个事件的发送目标是ActivityThread(APP进程), 由ActivityThread收到事件后进一步处理,所以
//这边涉及到了跨进程通信,binder跨进程通信的数据必须继承Parcelable数据类型实现序列化。
//这个类中主要包含三个内容:
1. private List<ClientTransactionItem> mActivityCallbacks; //activity的回调:如onstart,onresume,onpause等
2. 此变量定义了activity生命周期的最终状态(执行完一系列事件后的最终状态):private ActivityLifecycleItem mLifecyclesStateRequest.
3. 跨进程的目标进程:IApplicationThread mClient; //clientTransaction的发送目标。
4. 目标进程对应关联的Activity: private IBinder mActivityToken;
final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.apptoken);
//添加LauncherActivityItem.why?
clientTransaction.addCallback(LauncherActivityItem.obtain(new Intend(r.intent),... ));
if(andResume)
//最终的状态
lifecycleItem = ResumeActivityItem.obtain()
else
lifecycleItem = PauseActivityItem.obtain();
clientTransaction.setLiftcycleStateRequest(liftcycleItem); //设置ResumeActivityItem到事件中。
mService.getLiftcycleManager.scheduleTransaction(clientTransaction);//获取生命周期管理 类,并执行事务。
}else{ //如果APP进程不存在
mService.startProcessAsync(); //进入创建进程的流程。 这边的流程分支已经分析过了
}
}
- 下面开始分析第三阶段的工作任务(进程间通信):整体 流程如下图所示
前面第二阶段中,将mService.getLiftcycleManager.scheduleTransaction(clientTransaction);代码执行完就,就开始进入第三阶段的处理了。
图3
接着前面的代码进行分析,当拿到LifecycleManager对象之后,继续调用它的方法scheduleTransaction(), 进入代码:
mService.getLiftcycleManager.scheduleTransaction(clientTransaction);
mService是ATMS对象mService.getLiftcycleManager():它返回的是ClientLifecycleManager,它的初始化也是在ATMS的构造函数中,
ActivityTaskManagerService(Context context)
mLifecycleManager = new ClientLifecycleManager(); //28之后添加的对activity lifecycle的触发器
scheduleTransaction()://这个是执行 mLifecycleManager对象中的方法
-->//当前的进程还是存在于AMS所在的进程中。
transaction.schedule(); //transaction是ClientTransaction对象
-->会进入ClientTransaction.java->schedule(); //这个会完成一次跨进程通信
-->把this(自己)传递进入:就是ClientTransaction对象
-->mClient.scheduleTransaction(this); //通过mClient(目标进程的Binder)也就是IApplicationThread跨进程调用到应用进程
接着,现在源码转至APP进程的ActivityThread.java->scheduleTransaction(this):
-->ActivityThread.this.scheduleTransaction(transaction);
-->先来了解下ActivityThread extends ClientTransactionHandler,后者是ActivityThread的父类,
-->这里它调用的是父类ClientTransactionHandler中的方法scheduleTransaction:
//下面调用发送消息所在的线程不是主线程,它是在ApplicationThread线程中运行的,就是上面分析的mClient对象,它是IBinder对象,属于binder中的ApplicationThread对象
-->在里面调用了sendManager(ActivityThread.H.EXECUTE_TRANSACTION, transaction); //发消息给主线程:ActivityThread的Handler
-->ActivityThread的handleMessage():
-->ClientTransaction transaction = (ClientTransaction)msg.obj; //所以这个消息的传递总的来说,先跨进程,再跨线程,将封装的transaction传递过来
-->mTransactionExecutor.execute(transaction); //使用主线程中的触发器去执行transaction
-->//这里就进入到activity生命周期的触发管理执行
总结下第三阶段干的任务:上图3中的ClientTransaction流程中,会进行一次跨进程调用,进入到app的进程,在主进程中会调用Binder线程IAppicationThread中的方法(它是app的子线程),就是在ClientTransactionHandler中会向主线程发送消息,这里又进行了一次子线程向主线程的消息传递过程,主线程在处理的时候,就会调用真正的执行触发器 mTransactionExecutor 去执行对应的transaction,触发生命周期的管理。
- 下面分析Acitivity生命周期触发器执行阶段
/第四阶段:
mTransactionExecutor.execute(transaction); //上接第三阶段结束
-->executeCallbacks(transaction);
-->执行的是LauncherActivityItem: //在第二阶段中有添加这个callback
int size = callbacks.size();
for(int i = 0; i < size; ++i){ //从callback数组中取出item
ClientTransactionItem item = callback.get(i);
//调用launchActivityItem的execute方法
item.execute(mTransactionHandler, token, mPendingActtions);
-->进入launchActivityItem.java->execute:
//launcher启动activity时,还没有ActivityClientRecord,需要构建一个。
//这个是ActivityThread的静态内部类:ActivityClientRecord:处理client端事件的记录,启动过程中会使用
-->ActivityClientRecord r = new ActivityClientRecord();
client.handleLauncherActivity(r, pendingActions); //client:ClientTransactionHandler.java
//client唯一的实现类就是ActivityThread(继承ClientTransactionHandler)
//所以将会进入到ActivityThread.java->handleLauncherActivity():
-->final activity a = performLauncherActivity(r, customIntent);
-->构建一个activity
activity = mInstrumentation.newActivity();
//loadedAPk 构建makeApplication对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
-->如果Application已经存在,直接return,保证单例
if(mApplication != null){
return mApplication; //在前面分析的bindApplication()中实际上已经创建了Application.
}
//在这个方法中创建Activity的PhoneWindow, 并绑定对应的WindowManager.
activity.attach();
-->mWindow = new PhoneWindow(); //这里开始就进入了wms.
...
//执行onCreate生命周期
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
r.setState(ON_CREATE); //设置mLifecycleState成CREATE状态。 //这很关键
}
executeLifecycleState(transaction);
-->获取ActivityLifecycleItem,这里取的是之前添加的ResumeActivityItem
ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
//ResumeActivityItem的getTargetState 是ON_RESUME = 3
cycleToPath(r, lifecycleItem.getTargetState(), true, transaction);
-->start = r.getLifecycleState(); //这里的start是on_Create状态 = 1
-->下面的path:包括ON_START和ON_RESUME
-->这里是Activity执行onStart的函数的关键所在
-->//mHelper是TransactionExecutorHelper类对象,finish=lifecycleItem.getTargetState(), = ON_RESUME=3
-->IntArray path = mHelper.getLifecyclePath(start,finish,excludeLastState); //start = 1, finish = 3
-->if(finish > start) //3> 1
{
if(start == ON_START && finish == ON_STOP){
}else{ //走下面这个分支
for(int i = start +1; i <= finish; ++i){
mLifecycleSequence.add(i); //把ON_START和ON_RESUME添加到mLifecycleSequence中 。加入2和3
}
}
}
//excludeLastState = true;所以进入分支移除ON_RESUME
if(excludeLastState && mmLifecycleSequence.size()!=0){
mLifecycleSequence.remove(mLifecycleSequence.size() -1);//移除ON_RESUME;
}
return mLifecycleSequence; //里面只有ON_START=2这个状态了
//执行paht中相关的生命周期函数
performLifecycleSequence(r,path,transaction);
-->int size = path.size(); //只有一个ON_START
for(i= 0; i < size; ++i){
state = path.get(i);
switch(state){
case ON_START:
mTransactionHanlder.handleStartActivity(r.token, mPendingActions);
-->触发进行Activity的onStart流程。
//start
activity.performStart("handleStartActivity");
r.setState(ON_START);
break;
}
}
//执行ResumeActivityItem的execute
lifecycleItem.execute();//lifecycleItem = ResumeActivityItem
-->进入ResumeActivityItem.java->execute():
client.handleResumeActivity(); //把事件丢给ActivityThread去执行。
lifecycleItem.postExecute(r,path,...);
//上接: client.handleResumeActivity(); //把事件丢给ActivityThread去执行。
ActivityThread->handleResumeActivity():
-->r.activity.performResume(r.startsNotResume, reason);
r.setState(ON_RESUME);
总结:
LaunchActivityItem:
launch():
onCreate();
触发器的计算触发onStart();生命周期
最后是ResumeAtivityItem->onResume(); 这就包括了完整的生命周期过程,从onCrate->onStart->onStart();
- 第五阶段:activity的Stop阶段
下面分析:当Activity A--->Activity B时,B的启动和A的Stop处理如何操作?主要是A的Stop阶段如何进行?这个就是第5阶段,还是从ActivityThread的handleResumeActivity()中去分析,
大致由下图流程:
ActivityThread->handleResumeActivity():
-->ActivityClientRecord r = performResumeActivity(); //执行resume生命周期
...
//显示UI
wm.addView(decor,l);//调用windowsManagerImpl将decorView添加到window中 WMS阶段去研究吧
Looper.myQueue().addIdleHandler(new Idler()) ;//往 looper中添加Idler事件
//这个Idler中包括了一个相当重要的事务,包含了一个与AMS的通信。
//APP主线程当没有任何消息事务需要处理时,会去处理Idler的MessageQueue
class Idler implements MessageQueue.IdleHandler{
public bool queueIdle(){
IActivityManager am = ActivityManager.getService();
do{
am.activityIdle(a.token, a.createdConfig, stopProfiling);
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
}(a != NULL); //执行这里,说明主线程是空闲状态。
}
}
请看上图的流程中,ASS的第4步,会处理processStoppingAndFinishingActivities();
也就是说,当ActivityThread主线程空闲时,会执行activityIdle(),接着会通过ATMS调用ASS有activityIdleInternal(),然后会执行Stop Activity相关的操作,也就是ActivityA->ActivityB过程时,会先启动B,然后在空闲时,再处理A的Stop事件,就是在这里处理的。
所以先来看看ATMS->activityIdle():
ATMS->activityIdle():
//mStackSupervisor是对activity生命周期事件进行封装的模块。帮助activityState
mStackSupervisor.activityIdleInternal();
-->processStoppingAndFinishingActivities(); //需要停止需要终止的activity都在这里面处理。
-->for(int i = mStoppingActivies.size()-1; i >=0; --i){ //需要停止的遍历一遍
...
readyToStopActivities.add(s);
mStoppingActivies.remove(i);
}
-->for(int i = 0; i < numReadyStops; i++){
ActivityRecord r = readyToStopActivities.get(i);
if(r.finishing()){
r.destroyIfPossible(reason);
}else{
r.stopIfPossible(); //我们stop走这边
-->mATmService.getLifecycleManager().scheduleTransaction(); //把stop事件封装成一个Transaction事务。
-->final ClientTransaction clientTransaction = transactionWithState(); //封装
scheduleTransaction(clientTransaction);//调用,跨进程,传给application.
}
}
注意:在android12中,activityStack和ActivityStack已经不存在了,改成了Task.java,启动过程全部转接到Task.java中处理。总体的思路不变。
在Stop事件封装成Transaction后,发给Application线程处理,然后会进入到第4阶段的Activity生命周处理处理流程,只不过可能是Launcher进程(另外一个进程),当然如果是相同进程,则由本进程去处理。只不过对于Stop或Finish等事件,它的优先级不高,所以基本都会等到主线程不繁忙空间的时候去执行清理操作。