ATMS的Activity启动入口 startActivityAsUser
Instrumentation执行startActivity后,会来到ATMS的startActivityAsUser方法
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
......
// TODO: Switch to user app stacks here.
//通过ActivityStartController去获取一个ActivityStarter
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
ActivityStartController和ActivityStarter
这里出现了两个类ActivityStartController和ActivityStarter
ActivityStarter用于去解析Activity启动的参数,每一个Activity启动的时候都对应着一个ActivityStarter去解析它的参数。在ActivityStarter中包含了一个静态内部类Request,这个类或许非常恰当的说明ActivityStarter的作用。它的部分代码如下:
static class Request {
...
IApplicationThread caller;//我们的App的Binder,也代表着谁来调用我们的启动流程
Intent intent;
NeededUriGrants intentGrants;
// A copy of the original requested intent, in case for ephemeral app launch.
Intent ephemeralIntent;
String resolvedType;
ActivityInfo activityInfo;
ResolveInfo resolveInfo;
IVoiceInteractionSession voiceSession;
IVoiceInteractor voiceInteractor;
IBinder resultTo;
String resultWho;
int requestCode;//activity启动的返回结果
int callingPid = DEFAULT_CALLING_PID;
int callingUid = DEFAULT_CALLING_UID;
String callingPackage;
@Nullable String callingFeatureId;
int realCallingPid = DEFAULT_REAL_CALLING_PID;
int realCallingUid = DEFAULT_REAL_CALLING_UID;
int startFlags;
SafeActivityOptions activityOptions;
boolean ignoreTargetSecurity;
boolean componentSpecified;
boolean avoidMoveToFront;
ActivityRecord[] outActivity;
Task inTask;
String reason;
ProfilerInfo profilerInfo;
Configuration globalConfig;
int userId;
WaitResult waitResult;
int filterCallingUid;
PendingIntentRecord originatingPendingIntent;
boolean allowBackgroundActivityStart;
...
}
ActivityStartController是ActivityStarter的控制器,它控制着ActivityStarter的创建。在ATMS的init函数初始化,辅助ATMS去创建和管理ActivityStarter。
//ActivityStartController的obtainStarter方法
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
//在ActivityStarter静态内部类DefaultFactory
//在ActivityStartController构造函数里面被创建
static class DefaultFactory implements Factory {
/**
* The maximum count of starters that should be active at one time:
* 1. last ran starter (for logging and post activity processing)
* 2. current running starter
* 3. starter from re-entry in (2)
*/
private final int MAX_STARTER_COUNT = 3;
private ActivityStartController mController;
private ActivityTaskManagerService mService;
private ActivityStackSupervisor mSupervisor;
private ActivityStartInterceptor mInterceptor;
private SynchronizedPool<ActivityStarter> mStarterPool =
new SynchronizedPool<>(MAX_STARTER_COUNT);
DefaultFactory(ActivityTaskManagerService service,
ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
mService = service;
mSupervisor = supervisor;
mInterceptor = interceptor;
}
@Override
public void setController(ActivityStartController controller) {
mController = controller;
}
@Override
public ActivityStarter obtain() {
ActivityStarter starter = mStarterPool.acquire();
if (starter == null) {
starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
}
return starter;
}
@Override
public void recycle(ActivityStarter starter) {
starter.reset(true /* clearRequest*/);
mStarterPool.release(starter);
}
}
ActivityStartController创建ActivityStarter使用了享元设计模式
可以看到ActivityStartController创建ActivityStarter使用了享元设计模式,减少了内部抖动。每启动一个Activity都需要创建一个ActivityStarter 去解析Activity启动参数,这边设计了一个大小为3的缓存池,当ActivityStarter 使用完成后,初始化所有数据后放到池子里面,下一次不需要new出ActivityStarter,直接从池子里面拿就行了。
ActivityStarter的executeRequest创建Activity的实例 ActivityRecord对象,启动那些需要启动,但是一直没有来得及启动的Activitys,最后启动我们目标activity
通过ActivityStartController创建ActivityStarter,并且在ActivityStarter的Request里面保存下来相应的参数后,接下来执行ActivityStart的execute函数,execute会执行executeRequest函数
private int executeRequest(Request request) {
//拿出Request记录的Activity的相关参数
//检测判断这些参数是否合规
......
//创建出我们的目标 ActivityRecord对象,存到传入数组0索引上
//这一步已经创建出Activity的实例,Activty在Frameworks层就叫做ActivityRecord
final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, callingFeatureId, intent, resolvedType, aInfo,
mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
sourceRecord);
......
// 启动那些需要启动,但是一直没有来得及启动的Activitys
// 比如说一个屏幕里面同时存在两个Activity,,最后也是调用startActivityUnchecked启动activity
mController.doPendingActivityLaunches(false);
//启动最后需要启动的activity,也就是当前activity
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
......
return mLastStartActivityResult;
}
executeRequest函数里面先拿出Request记录的Activity的相关参数,检测判断这些参数是否合规。接着创建出我们的目标 ActivityRecord对象,存到传入数组0索引上。这一步已经创建出Activity的实例,Activty在Frameworks层就叫做ActivityRecord。接下来启动那些需要启动,但是一直没有来得及启动的Activitys,比如说一个屏幕里面两个Activity。最后才是启动我们目标activity。
startActivityInner方法里面初始化配置,计算要启动的Activty的栈和源Activity所在的栈,然后将启动模式塞到mIntent里面。在把启动流程交给RootWindowContainer之前,创建了一个黑白屏window
我们调用startActivityUnchecked方法启动目标activity的时候,会跑到startActivityInner方法里面。
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
//初始化配置,mStartActivity、mLaunchMode等
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
// 计算要启动的Activity的task标志,也就是计算启动模式
computeLaunchingTaskFlags();
//计算源Activity所在的Stack
computeSourceStack();
//将mLaunchFlags设置给Intent,也就是设置启动模式
mIntent.setFlags(mLaunchFlags);
......
// 创建启动黑白屏window
mTargetStack.startActivityLocked(mStartActivity,
topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions);
......
//把我们的启动流程交给RootWindowContainer
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
......
}
在startActivityInner方法里面初始化配置,计算要启动的Activty的栈和源Activity所在的栈,然后将启动模式塞到mIntent里面。在把启动流程交给RootWindowContainer之前,创建了一个黑白屏window,这是为什么呢?
为什么创建了一个黑白屏window
因为如果是从Launcher程序启动我们的App的mainActivty的话,启动流程执行到这里,App进程是还没有被创建的。我们在ActivityStackSupervior类里面才去判断App进程是否存在,不存在则通过ZygoteProcess给ZygoteService发送一个socket信息,ZygoteService收到socket信息才会fork出我们的app进程。这是一个缓慢的过程。如果不弄一个黑白屏幕去相应用户的点击事件,用户点击后往往要几秒钟才会启动MainActivity,用户会以为没有点击到图标,可能会疯狂点击。
为什么要交给RootWindowContainer去执行接下来的启动流程
我们的启动流程在ActivityStartController创建ActivityStarter,ActivityStarter解析相应的参数,并且计算好要启动的Activity栈信息,源Activty的栈信息,启动一个黑白屏后,为什么要交给RootWindowContainer去执行接下来的启动流程?
RootWindowContainer是窗口容器(WindowContainer)的根容器,管理了所有窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。窗口又是需要依赖Activity存在的,基于这层关系,我猜测设计的时候干脆把Activty启动流程的一些步骤交给RootWindowContainer。