前言
重温四大组件第四篇,这里分析一下Activity的启动过程。Activity的启动过程分为两种,一种是根Activity的启动,另外一种是普通Activity的启动过程。根Activity也就是默认启动的Activity(在AndroidMinifest.xml配置的启动Activity)。普通Activity指的是除根Activity的其他Activity。其中根Activity和普通Activity的启动过程略有区别,根Activity的启动过程涉及到了应用程序进程的启动过程。
接下来从根Activity的角度启动来说。
以下分析的代码基于Android 9.0
Activity启动过程中的数据结构
我们在看一些技术博客的时候经常会看到一些分析AMS的文章。AMS就是ActivityManagerService,顾名思义就是Activity的管理服务,但它不仅仅管理Activity,其他三个组件的启动也经由AMS。同时,在看Activity的启动过程之前,我们应该了解一些Binder的知识。Binder是Android系统中一种跨进程通信技术。在Activity的启动过程中就涉及到了Binder通信的过程。
Activity的启动过程,可以概括为Launcher到AMS(经过Binder通信),从AMS到ApplicationThread(通过Binder通信)。
以上介绍了AMS在Activity的启动中承担的作用。接下来,我们再介绍一些在Activity启动过程中的一些其他角色。
ActivityStack
从ActivityStack的命名可以看出这个是Activity栈相关的。它的作用是管理和记录一个Activity栈的Activity。接下来我们看下ActivityStack中有哪些属性。
名称 | 类型 | 说明 |
---|---|---|
mService | ActivityManagerService | 目前AMS的引用 |
mRecentTasks | RecentTasks | 记录一个最近使用的Activity列表 |
mPausingActivity | ActivityRecord | 目前停止状态的Activity信息 |
mResumedActivity | ActivityRecord | 目前resume状态的Activity信息 |
ActivityRecord
ActivityRecord是用来描述一个Activity的数据结构,它记录了Activity的所有信息。
名称 | 类型 | 说明 |
---|---|---|
service | ActivityManagerService | 目前AMS的引用 |
info | ActivityInfo | 主要记录了Activity在Manifest文件中的配置信息 |
launchedFromPid | int | 启动Activity进程的pid |
launchedFromUid | int | 启动Activity进程的uid |
taskAffinity | String | Activity启动后所在的task |
task | TaskRecord | 记录了所在task的信息 |
app | ProcessRecord | 记录了Activity启动所在进程的信息 |
state | ActivityState | 当前Activity的状态 |
theme | int | Activity的主题 |
TaskRecord
TaskRecord是关于任务栈的描述。
名称 | 类型 | 说明 |
---|---|---|
taskId | final int | 任务栈的唯一标识 |
affinity | String | 任务栈的名称,也就是taskAffinity配置的名称 |
intent | Intent | 启动这个任务栈的Intent |
mActivities | ArrayList | 按照在任务栈中历史顺序排序的Activity |
mStack | ActivityStack | 任务栈所在的Activity栈 |
mService | ActivityManagerService | 目前AMS的引用 |
ProcessRecord
ProcessRecord是关于应用进程的描述。
名称 | 类型 | 说明 |
---|---|---|
uid | int | 进程的uid |
processName | String | 进程名称 |
info | ApplicationInfo | 记录应用程序信息 |
在上面介绍了Activity启动过程中关于Activity启动过程中的一些信息记录。比如:Activity栈信息、任务栈信息以及进程信息等。
Activity的启动工程
Activity的启动过程是一个很复杂的过程,接下来的分析过程并不会把所有细节都分析到位。我们分析Activity的启动过程主要是为了学习Android系统对Activity组件的管理过程以及对应用进程的调度。
从Launcher到AMS
我们知道在Android系统中锁呈现的桌面就是一个应用程序。当用户点击桌面上的应用图标是就可以启动相应的应用程序。应用程序由Launcher启动,调用startActivitySafely()方法。
/**Launcher.java**/
boolean startActivitySafely(Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
}
return false;
}
复制代码
可以看到在startActivitySafely()中继续调用startActivity()方法启动Activity,并且在Intent中设置了flag为FLAG_ACTIVITY_NEW_TASK表示Activity将在一个新的任务栈中启动。这个方法就是在Activity中的。
/**Activity.java**/
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
复制代码
这里继续调用了startActivityForResult(),并且requestCode为-1表示Launcher不需要知道Activity的结果。
/**Activity.java**/
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//继续启动Activity
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
复制代码
在这里先判断mParent是否为null,然后根据结果选择走那一步。如果跟代码的话,可以看到mParent在attach()方法中或者setParent()方法中赋值,在根Activity的情况中mParent为null。所以继续调用 mInstrumentation.execStartActivity()。
/**Instrumentation.java**/
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
//......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//通过Binder接口获取AMS对象
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
复制代码
在上面的方法中继续启动Activity,在这里我们可以看到通过ActivityManager.getService()我们就获取到了AMS对象。接下来,我们看下AMS的获取过程。
/**ActivityManager.java**/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
复制代码
在getService()方法中通过IActivityManagerSingleton获取了AMS的对象。在创建IActivityManagerSingleton的方法中我们可以看到返回的是IActivityManager,IActivityManager就是使用了AIDL的方式生成的。
在AMS中处理Activity的启动
从这里开始,Activity的启动就开始在AMS中进行了。从上面的代码可以知道这个过程是通过Binder通信方式进行的。
/**ActivityManagerService.java**/
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
复制代码
在ActivityManagerService中通过startActivity()方法继续进行Activity的启动。接下来我们直接看最终的方法回调。
/**ActivityManagerService.java**/
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
//......
//从obtainStarter()中获取了ActivityStarter对象
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId) //设置mayWait标志
.execute();
}
复制代码
在上面的方法中,AMS通过startActivityAsUser()方法最终把Activity的启动过程转移到了ActivityStarter中。我们直接看下ActivityStarter的execute()方法。
/**ActivityStarter**/
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
//....//);
} else {
return startActivity(mRequest.caller, mRequest.intent, //....//);
}
} finally {
onExecutionComplete();
}
}
复制代码
这里根据mRequest.mayWait(表示我们应该等待启动请求的结果。)中的标志来判断走哪个逻辑分支。在上面的代码中调用setMayWait(userId),这里将mayWait设置为true。那么接下来我们继续看startActivityMayWait()方法。
private int startActivityMayWait(//....//) {
//......
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); //构建Activity的信息
synchronized (mService) {
final ActivityStack stack = mSupervisor.mFocusedStack; //获取Activity栈的信息
stack.mConfigWillChange = globalConfig != null
&& mService.getGlobalConfiguration().diff(globalConfig) != 0;
//......
final ActivityRecord[] outRecord = new ActivityRecord[1]; //获取Activity的信息
//继续启动Activity
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup);
Binder.restoreCallingIdentity(origId);
//......
return res;
}
}
复制代码
我们继续跟代码,接下会调用
private int startActivity(//....//) {
//......
ProcessRecord callerApp = null; //获取进程信息
if (caller != null) {
//caller是ActivityThread中的Binder接口,用过应用程序进程则不为null
callerApp = mService.getRecordForAppLocked(caller); //获取进程信息
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
}
}
//......
//创建启动Activity的信息类
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
final ActivityStack stack = mSupervisor.mFocusedStack; //获取有焦点的Activity栈
//......
//继续启动Activity
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
复制代码
在上面会看到根据IApplicationThread获取应用进程信息,这里如果应用进程没有被创建的时候,IApplicationThread是null,然后接下来的步骤会创建应用程序进程,这里不再详细说。接下来继续进行Activity启动的分析。
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
//......
int result = START_SUCCESS;
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mService.mWindowManager.executeAppTransition();
} else {
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
//这里继续启动Activity
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
}
return START_SUCCESS;
}
复制代码
接下来启动Activity的过程转到ActivityStackSupervisor中。
/**ActivityStackSupervisor**/
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//这里从Activity栈中启动
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
//......
return false;
}
复制代码
上面的代码中继续启动Activity,这次启动过程转到ActivityStack中。
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//......省略代码
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
//这里如果mResumedActivity不为null,就停止mResumedActivity
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
//next是ActivityRecord对象,next.app是ProcessRecord对象,next.app.thread是IApplicationThread
if (next.app != null && next.app.thread != null) {
//如果都不为null,说明应用进程已经被创建
//......
synchronized(mWindowManager.getWindowManagerLock()) {
try {
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
}
} else {
应用进程没有被创建
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
复制代码
在上面的代码中我们可以看到有一个判断逻辑if (next.app != null && next.app.thread != null),这个是判断应用程序进程是否被创建,从代码中可以看到,无论应用进程是否被创建,都会调用startSpecificActivityLocked()方法。这里Activity的启动又转移到了ActivityStackSupervisor中。
除此之外,还有一个步骤是将mResumedActivity设置为停止状态,在我们查看Activity的生命周期时,一个Activity启动另外一个Activity的时候,在调用过Activity的pause生命周期函数时才会开始下一个Activity的生命周期。
/**ActivityStackSupervisor**/
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
//获取应用进程信息
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
mService.mProcessStats);
}
//继续启动Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
}
}
//创建应用进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
复制代码
这里就看到了如果应用进程不存在就会通过AMS创建应用进程,这里不再展开分析。如果应用进程存在就继续启动Activity。调用了realStartActivityLocked方法。
/**ActivityStackSupervisor**/
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//......
// Create activity launch transaction.
//Android 9.0的启动方式与其他版本的不同,这里换成了通过ClientTransaction的方式已启动。
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
// 这里用来处理Activity生命周期回调
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
复制代码
在上面可以看到Android 9.0的启动方式与其他版本的不同,在Android 9.0里主要通过回调的方式启动Activity,最终会通过AMS中的ClientLifecycleManager.scheduleTransaction()方法调用ApplicationThread的scheduleTransaction(),最后的是执行的LaunchActivityItem的execute()方法。
/**TransactionExecutor**/
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
//1.先执行CallBack
executeCallbacks(transaction);
//2.再执行Activity生命周期回调
executeLifecycleState(transaction);
mPendingActions.clear();
}
复制代码
/**LaunchActivityItem**/
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
复制代码
可以看到这里调用了ClientTransactionHandler的handleLaunchActivity()方法。从这里Activity的启动过程就从AMS中的调用切换到了ActivityThread中去了。
从AMS到ActivityThread
上面说到,Activity的启动调用了ClientTransactionHandler的handleLaunchActivity()方法。我们可以发现ActivityThread是继承自ClientTransactionHandler的。在ClientTransactionHandler中handleLaunchActivity是抽象方法,我们直接在ActivityThread中看。
从这里开始将开始执行Activity的生命周期函数。
/**ActivityThread**/
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//......
//初始化WindowManagerService
WindowManagerGlobal.initialize();
final Activity a = performLaunchActivity(r, customIntent);
//......
return a;
}
复制代码
可以看到在这里继续调用了
/**ActivityThread**/
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//......
Activity activity = null;
try {
//获取Activity实例
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
//......
}
try {
//初始化Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//设置Context
appContext.setOuterContext(activity);
//调用Activity的attach()方法
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
if (r.isPersistable()) {
//调用onCreate()生命周期函数
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.mInstrumentation(activity, r.state);
}
//......
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme); //设置主题
}
//......
r.activity = activity;
}
r.setState(ON_CREATE);
}
//......
return activity;
}
复制代码
在上面的代码可以看到执行完Activity的attach()方法后,继续执行Instrumentation的callActivityOnCreate()方法。
/**Instrumentation**/
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
复制代码
这里可以看到,又执行了Activity的performCreate()方法。
/****/
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
//....
//调用onCreate()生命周期方法
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
}
复制代码
在上面的代码中调用了Activity的onCreate()生命周期方法。到这里,在上面讲到的TransactionExecutor的execute()方法中的回调已经执行完毕,接下来就是开始执行生命周期相关的回调。
我们在分析上面代码的时候知道,生命周期回调是一个ResumeActivityItem。
/**ResumeActivityItem**/
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
复制代码
可以看到这里有调用了handleResumeActivity()方法。
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
}
复制代码
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
//执行Activity的performResume
r.activity.performResume(r.startsNotResumed, reason);
r.state = null;
r.persistentState = null;
r.setState(ON_RESUME);
} catch (Exception e) {
}
return r;
}
复制代码
在上面的代码中调用了Activity的performResume()方法。进而调用Activity的onResume()方法。这时Activity就呈现到了界面。Activity也算启动完成。
总结
上面以根Activity的视角分析了Activity的启动过程。整个分析下来,感觉到Activity的启动还是十分复杂的,但是在也并不需要面面俱到,能够把握大体,流程理解Android在启动Activity的过程中是怎么调度的,这样就达到了我们的目的。