为什么需要了解Activity启动流程
从笔者个人的的视角出发,对系统源码的了解,可以从一定上加深我们对业务中一些页面或者组件的行为的理解。以AMS这个流程为例,你可以了解到一些启动activity时候的一些调度行为,了解一些深层次的原因,那么我们在业务开发 和 在一些问题修复 以及处理一些性能问题的时候 可以多一些额外的视角。
举个🌰,我们在想办法降低页面TTI的时候,如果我们知道整个activity启动流程并且知道他是有一定耗时的,是不是就能很快去想到能不能把一些页面的加载行为和这个AMS的流程去异步并行,比如从点击那一刻开始加载,而不是等待进入到页面之后再去加载数据,通过这种思路来前置进行这些数据加载的行为。(仅代表个人的看法和思路,欢迎大家补充)
OK,下面我们就来整体捋一下这整一个流程。
总体的梳理思路
首先就是入口,众所周知,就是Activity.startActivity()。 另外在看源码之前,我们先抛一下粗粒度的流程:
- startActivity是在客户端进程中发起的
- 但是页面数据的装载是在system_server进程(AMS服务)中处理的
- 然后最终仍然要回到客户端进程中执行真正的Activity创建和生命周期调度
所以流程上是 应用进程 -> AMS服务 -> 应用进程,下面我们从这三个阶段分别去分析他们中流程的一些行为
第一阶段:应用进程 - 拉起AMS服务
- 从startActivity方法开始看 (仅列关键方法)
class Activity {
public void startActivity(Intent intent, @Nullable Bundle options) {
...
startActivityForResult(intent, -1, options);
...
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
...
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
}
- 看到最终调用了Instrumentation对象的execStartActivity方法,接着往下看
public class Instrumentation {
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
...
}
}
- 看到调用了ActivityTaskManager.getService(),发起了startActivity。然后具体看一下这个ActivityTaskManager.getService()去拿了哪个service
class ActivityTaskManager {
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
}
- 发现他通过ServiceManager.getService去拿了系统的AMS服务,然后通过IActivityTaskManager.Stub.asInterface(b)去具象化了这个对象,然后通过这个对象去发起IPC通信。这个时候就走到了AMS服务的逻辑。
第二阶段:AMS服务进程 - 定义一些创建行为
- 继续看IActivityTaskManager的实现类ATMS的startActivity方法
class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage, ...) {
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();
}
}
- 会走到startActivityAsUser方法中,先用getActivityStartController().obtainStarter去创建一个ActivityStarter对象,然后用拼接一些activiy的信息,最后调用excute()。 下面就看下excute()方法里面做了什么。
class ActivityStarter {
int execute() {
...
synchronized (mService.mGlobalLock) {
...
res = executeRequest(mRequest);
...
}
...
}
private int executeRequest(Request request) {
...
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
...
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
}
}
- 可以看到在这个ActivityStarter里面做了两件事情,先是把这个Activity的信息塞到这个ActivityRecord对象里面,然后带着这个ActivityRecord对象继续往下走startActivityUnchecked方法,接着往下看
class ActivityStarter {
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
...
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...
computeLaunchingTaskFlags();
mIntent.setFlags(mLaunchFlags);
...
mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
mStartActivity.getUriPermissionsLocked());
...
mRootWindowContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);
...
}
}
- 可以看到最终进入了startActivityInner方法,在这个方法里面又去新增了一些activity的信息:比如计算启动模式和给Activity添加Uri权限,然后再最后调用resumeFocusedStacksTopActivities继续往下走
class RootWindowContainer {
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
final Task focusedRoot = display.getFocusedRootTask();
if (focusedRoot != null) {
result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
}
}
- 调用一个Task对的resumeTopActivityUncheckedLocked
class Task extends TaskFragment {
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
final TaskFragment topFragment = topActivity.getTaskFragment();
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
...
}
}
class TaskFragment extends WindowContainer<WindowContainer> {
...
mTaskSupervisor.startSpecificActivity(next, true, false);
...
}
- 继续看 mTaskSupervisor.startSpecificActivity里面干了啥
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
...
if (wpc != null && wpc.hasThread()) {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
}
...
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
}
- 首先通过wpc.hasThread()判断ApplicationThread是否被赋值(也就是应用进程是否被创建),如果未创建调用ATMS的startProcessAsync去创建进程;否则realStartActivityLocked去继续创建activity,继续看realStartActivityLocked的实现
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), 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.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
r.getLaunchedFromBubble()));
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
8.简单描述一下realStartActivityLocked做的事情
(1)通过ClientTransaction.obtain新建的一个clientTransaction任务流
(2)往clientTransaction通过addCallback塞一个LaunchActivityItem对象,很明显看名字也知道这个对象是用于创建和启动activity用的
(3)setLifecycleStateRequest(ResumeActivityItem),看名字这个对象的作用应该是把activity的生命周期推到onResume
(4)最后通过mService.getLifecycleManager().scheduleTransaction提交这个clientTransaction,下面继续看一下这个方法干了啥
class ClientLifecycleManager {
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
...
}
}
class ClientTransaction {
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
}
- 可以看到client是应用进程的ApplicationThread对象在AMS中的代理,调用scheduleTransaction(this)后,又把ClientTransaction打包回到了应用进程。原因是因为在AMS里他只是定义了应用在创建activity需要做什么,而实际的操作仍然需要回到activty中去进行。 所以下进入第三阶段
第三阶段:应用进程 - 实际创建activity
public final class ActivityThread extends ClientTransactionHandler {
private class ApplicationThread extends IApplicationThread.Stub {
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) {
Message msg = Message.obtain();
...
msg.obj = obj;
...
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
}
}
- 看到ApplicationThread.scheduleTransaction会走到ActivityThread.scheduleTransaction, 然后会把这个transaction打包成一个message,然后通过mH这个Handler发送到主线程。然后继续看mH收到EXECUTE_TRANSACTION消息后去干了啥。
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
}
public class TransactionExecutor {
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
}
- 去调用mTransactionExecutor.excute去解析和真正执行这个transaction。然后他分别调用了executeCallbacks和executeLifecycleState这两个方法。下面分别去看下里面具体做了啥
(1)首先来看executeCallbacks
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
...
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...
item.execute(mTransactionHandler, token, mPendingActions);
}
}
getCallbacks里面的内容就是上面ams往这个transaction添加的LaunchActivityItem, 然后继续执行了LaunchActivityItem.excute(), 继续看下这个里面做了啥
public class LaunchActivityItem extends ClientTransactionItem {
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
}
调用ClientTransactionHandler.handleLaunchActivity, 这个方法的具体实现在AcitivityThread中,继续往下看。
class ActivityThread {
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
..
final Activity a = performLaunchActivity(r, customIntent);
..
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
mInstrumentation.callApplicationOnCreate(app);
...
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,
r.assistToken, r.shareableActivityToken);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
}
这个方法分别做了以下这些事情:
第一步通过activtyRecord中的信息加载Activity类,然后通过mInstrumentation.newActivity去创建可这个activity对象;
第二步通过makeApplication去创建Application对象,然后通过mInstrumentation.callApplicationOnCreate(app)去走Application的onCreate方法;
第三步调用activity的attach方法去初始化一些activity的数据;
第四步调用mInstrumentation.callActivityOnCreate去把activity的生命周期推到onCreate
(2)然后看第二个方法executeLifecycleState(transaction)具体去做了啥
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
}
首先通过transaction.getLifecycleStateRequest()拿到了一个ActivityLifecycleItem对象,这个getLifecycleStateRequest拿到的对象就是我们在第二个阶段中塞进去的ResumeActivityItem, 然后调用了这个ResumeActivityItem的excute(), 往下看
public class ResumeActivityItem extends ActivityLifecycleItem {
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
}
}
class ActivityThread {
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, String reason) {
...
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
...
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
..
wm.addView(decor, l);
...
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
...
}
}
里面主要干了两件事情:
调用performResumeActivity把activity的生命周期推到onResume
把decorView加到wm上,并开始测量,布局,绘制,最后展示出来。
到这里activity就被创建完成了。
总结
简单再捋一下逻辑,
- 首先创建activity这个命令startActivity是由应用进程发起的,
- 然后通过IPC调度到system_server进程,由AMS组装activity信息和编排activity的一些调度任务,并把所有的信息打包成一个ClientTransaction
- 最后再把ClientTransaction交给应用进程,应用进程通过handler把这个ClientTransaction丢给主线程,然后再去解析和执行这个ClientTransaction 去真正的创建activity和执行activity生命周期的调度