本文基于Android 9.0讲解下Activity的启动流程
Activity启动流程大致分为20几步
1:Activity的startActivity
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);
}
}
2:startActivityForResult
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
Uri referrer = onProvideReferrer();
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}
3:Instrumentation执行execStartActivity
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent); //检查activity启动结果
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
在这一步会检查activity的启动结果,譬如当activity没有在配置文件中注册的时候会报; have you declared this activity in your AndroidManifest.xml?"
四大组件的解析都是通过PackageParser这个工具类来解析的,构建一个ActivityInfo,ServiceInfo,ProviderInfo信息,如果ActivityInfo等为空的话,并且intent传递的组件compent不为空,那么就会抛出异常
4:进入到AMS的startActivity方法
@Override
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());
}
根据用户id来启动activity,有多用户的概念,这是一个跨进程的过程
5:继续调用同名的方法startActivityAsUser
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) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
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)
.execute();
我们可以看到mActivityStartController是一个ActivityStartController对象,其调用了obtainStarter方法来获取一个ActivityStarter对象,从而启动任务交给了ActivityStarter
6: 进入到ActivityStarter的execute方法
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}
} finally {
onExecutionComplete();
}
}
由于我们在AMS的startActivityAsUser中调用了setMayWait方法,也就是ActivityStarter的setMayWait方法,所以第一个if判断条件满足
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
7:进入ActivityStarter的startActivityMayWait方法
该方法有三个比较重要的信息点
1:解析intent信息构建一个ResolveInfo
2:根据ResolveInfo信息构建一个ActivityInfo信息
3: 调用startActivity方法返回启动结果
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);
ResolveInfo和ActivityInfo均是通过调用PackageParser的相关方法解析得到的信息
8:startActivity方法
该方法会继续调用同名的startActivity方法
9:同名的startActivity方法
这个方法里面主要做了几件事情
1:获取启动该activity的进程ProcessRecord,如果该进程caller为空,那么就认为没有权限启动该activity,返回的错误码是err = ActivityManager.START_PERMISSION_DENIED;也就是没有权限启动
2: 获取调用者activityRecord,ActivityRecord在system_server代表一个activity对象
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Will send result to " + resultTo + " " + sourceRecord);
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
3:错误判断
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
// We couldn't find a class that can handle the given Intent.
// That's the end of that!
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
// We couldn't find the specific class specified in the Intent.
// Also the end of the line.
err = ActivityManager.START_CLASS_NOT_FOUND;
}
如果无法解析出compent或是aInfo为空则返回对应的错误码
4:构建出ams端的一个activityrecord对象
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
上面的callingpid,callinguid在此处有体现
10:继续执行同名的startActivity方法
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
11:执行startActivityUnchecked
1:主要是计算启动activity的flag
computeLaunchingTaskFlags();
computeSourceStack();
2: 获取是否有可以复用的activity
ActivityRecord reusedActivity = getReusableIntentActivity();
3: 如果存在可以复用的activity,那么则复用该activity,并且回调onnnewintent方法
deliverNewIntent(top);
4:判断是否需要重新创建一个task,如果带有new_task_flag那么就会创建一个新的task
5: 调用ActivityStatck的mTargetStack.startActivityLocked方法
12:ActivityStack的startActivityLocked
1:向wms添加token值
if (r.getWindowContainerController() == null) {
r.createWindowContainer();
}
2:调整activity在task中的位置,将其放在顶部
这个方法主要是如果创建了新的task那么将新的task至于Stack的前台,如果没有新建task那么则插入到task的顶部
insertTaskAtTop(rTask, r);
3:准备activity的切换动画
mWindowManager.prepareAppTransition(transit, keepCurTransition);
4:添加一个启动窗口
r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
13:调用resumeFocusedStackTopActivityLocked
14:调用targetStack.resumeTopActivityUncheckedLocked
15:resumeTopActivityInnerLocked
1:先暂停处于resumed状态的activity
pausing |= startPausingLocked(userLeaving, false, next, false);
2: 启动下一个activity
mStackSupervisor.startSpecificActivityLocked(next, true, true);
3: 将该activity组件的状态设置成非stopped状态
16:startSpecificActivityLocked
1:设置activity的启动时间
getLaunchTimeTracker().setLaunchTime(r);
2:判断进程是否存在,如果存在则直接启动activity
realStartActivityLocked(r, app, andResume, checkConfig);
否则构造fork一个新的进程
17:假设进程存在,创建一个activity启动的事物ClientTransaction
1:添加一个回调
clientTransaction.addCallback,
参数是ClientTransactionItem类型的,其中有一个方法execute,会构建一个activityclientrecord对象,并且调用ClientTransactionHandler的handleLaunchActivity方法
2:开始执行回调
mService.getLifecycleManager().scheduleTransaction(clientTransaction)
调用的是ClientLifecycleManager的方法
transaction.schedule();进一步调用的是ClientTraction的schedule方法
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
此处的mclient是一个private IApplicationThread mClient;
进入到了app进程
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
由于class ActivityThread extends ClientTransactionHandler继承的是ClientTransactionHandler对象,那么调用的是父类的
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
18:发送一个消息到ActivityThread的主线程
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
这个方法的实现在子类ActivityThread中
19:对消息的处理
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
进而执行execute方法
20:mTransactionExecutor的execute方法的执行
也就是TransactionExecutor的execute方法
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
21:executeLifecycleState方法的调用
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
lifecycleItem 是ActivityLifecycleItem类型的对象
而ActivityLifecycleItem是一个抽象类
会调用两个关键的方法
executeCallbacks(transaction);
executeLifecycleState(transaction);
1:executeCallbacks,会调用item的excute方法
item.execute(mTransactionHandler, token, mPendingActions);
这个item是从list数组中取出来的
final ClientTransactionItem item = callbacks.get(i);
添加的位置在ActivityStackSuperVisor的realStartActivity方法
clientTransaction.addCallback(LaunchActivityItem
其类型是LaunchActivityItem类型
22:执行LaunchActivityItem的excute方法
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);
Client是ClientTransactionHandler类型的数据,也就是ActivityThread,进入执行到ActivityThread的handleLaunchActivity方法
23:ActivityThread的handleLaunchActivity方法
24:performLaunchActivity
主要是通过反射的机制创建一个activity对象,调用其attach方法,并且执行oncreate方法,也就是activity的oncreate方法可能被回调到,attach方法主要做了三件事情
1:关联一个context对象
2:创建phonewindow对象
3:为activity设置windowmanager对象
25:执行完成executeCallbacks方法执行executeLifecycleState方法
在执行完performLaunchActivity之后会设置其生命周期的状态值r.setState(ON_CREATE);
看看
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
具体的实现
我们在ActivityStackSuperVisior中的realStartActivity方法中有设置我们启动activity之后期望的目标状态
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
很显然我们期望的状态是Resumed状态
executeLifecycleState的入口有一个重要的方法
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
此时lifecycleItem对象应该是ResumeActivityItem类型的对象
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
ResumeActivityItem的目标状态是ON_Resumed的
接下来看cycleToPath的计算
调用的是同名的cycleToPath,并且不包含最后的状态
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
start值的计算为
final int start = r.getLifecycleState();也就是ON_CREATE状态
finish状态值也就是ON_RESUMED状态
if (finish >= start) {
// just go there
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
根据上面的计算很显然是进入到该判断条件,也就是添加了两种状态onstart,onresume
然后执行方法
performLifecycleSequence(r, path);
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
也就是回调ActivityThread的handleStartActivity和handleResumeActivity方法
26:handleStartActivity方法不需要重复说明
27:handleResumeActivity方法
该方法主要是将decorView添加到windowmanager里面,并且将窗口类型设置为
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
然后调用activity的makeVisibile方法将其设为可见状态
这样一个activity基本启动完成,后续的便是窗口的添加,relayout等其他操作
网友评论