学习Android,有的东西总是绕不过,比如Acticity的启动流程源码学习,这个之前面试的时候准备看,但是发现太复杂了,没太多时间,现在找到新工作了,接触Replugin的时候涉及到,Activity的启动,就顺道一起学习下。
Activity的启动流程:
不同的Android版本启动流程上代码会有不同,本文基于Android 11,学习activity的启动流程
Activity启动client端调用流程:
当用户在界面手点击屏幕上的应用图标时,应用程序的MainActivity是由Launcher启动的,
boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
try {
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}
Launcher在启动应用程序的时候,会调用上面的startActivitySafely来启动对应的Activity
这个startActivitySafely我们可以看到对startActivity启动的时候catch了ActivityNotFoundException的异常,这个很重要,因为有时候拉起的activity不存在也不至于你自己的app崩溃了
系统中应用安装的时候,PackageManagerService会对应用的AndroidManifest文件进行扫描,会获取到对应的组件信息,Launcher会通过Action和Category去查询所有对应的组件信息,也包括图标,这样用户点击的时候就会去启动对应的Activity。
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
...
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);
}
}
startActivity最终会去调用Activity#startActivityForResult,-1表示不需要执行结果
- Activity#startActivityForResult
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
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());
}
...
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
上面的代码中mParent代表的是ActivityGroup,ActivityGroup醉在用来在一个界面中引入多个activity,但是在api13中已经废弃了,系统推荐使用Fragment来代替ActivityGroup,因此mParent就会为null,所以我们关注半部分mParent==null的逻辑即可。
2. Instrumentation#execStartActivity
if逻辑中调用到了Instrumentation#execStartActivity函数
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
- Instrumentation: 该类负责Activity和Application的创建和生命周期的调用,同时监控系统与应用程序的所有交互
上面的代码可以看到调用了ActivityTaskManager.getService().startActivity()获取ActivityTaskManagerService去启动activity,
Android10及以前,启动Activity这里使用的是AMS,可能不想AMS的代码过于复杂,11就将原本AMS中的
System service for managing activities and their containers (task, stacks, displays,… ).
activity的task,stack,显示相关的功能分离到ActivityTaskManagerService中进行
调用了ActivityTaskManager.getService().startActivity()去启动Activity之后,会返回服务端启动的result,checkStartActivityResult会对服务端启动结果进行校验,然后返回。
ActivityTaskManager.getService()返回的是一个IActivityTaskManager对象,用于跨进城调用ATMS的startActivity方法
/** @hide */
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
- IActivityTaskManager对象是ATMS在app进程中的代理对象,ActivityTaskManagerService实现了IActivityTaskManager.Stub。
client端调用流程

服务端调用流程
ATMS#startActivity会调用到下面的函数中ActivityTaskManagerService#startActivityAsUser::
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) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
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();
}
上面的return语句构造了ActivityStarter,这个类携带了相关的参数,用于确定intent和flag应该如何转换为activity,以及堆栈的转换逻辑。
ActivityStarter#execute函数中,
int execute() {
try {
// Refuse possible leaked file descriptors
if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
...
// If the caller hasn't already resolved the activity, we're willing
// to do so here. If the caller is already holding the WM lock here,
// and we need to check dynamic Uri permissions, then we're forced
// to assume those permissions are denied to avoid deadlocking.
if (mRequest.activityInfo == null) {
mRequest.resolveActivity(mSupervisor);
}
int res;
synchronized (mService.mGlobalLock) {
...
res = executeRequest(mRequest);
...
} finally {
onExecutionComplete();
}
}
ActivityStarter#execute主要执行逻辑在ActivityStarter#executeRequest中:
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
ActivityStarter#executeRequest方法中会去调用ActivityStarter#startActivityUnchecked启动activity
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
...
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
...
postStartActivityProcessing(r, result, startedActivityStack);
return result;
}
调用了ActivityStarter#startActivityInner之后,
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
...
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
...
return START_SUCCESS;
}
startActivityInner启动了一个活动,并去判断这个活动是否应该添加到现有活动的顶部,最后关键处调用RootWindowContainer#resumeFocusedStacksTopActivities
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!mStackSupervisor.readyToResume()) {
return false;
}
boolean result = false;
if (targetStack != null && (targetStack.isTopStackInDisplayArea()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
if (!resumedOnDisplay) {
// In cases when there are no valid activities (e.g. device just booted or launcher
// crashed) it's possible that nothing was resumed on a display. Requesting resume
// of top activity in focused stack explicitly will make sure that at least home
// activity is started and resumed, and no recursion occurs.
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
接着又会去调用:ActivityStack#resumeTopActivityUncheckedLocked
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
// When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
- 这里的函数名称带了个Locked,这个不太清楚啥意思,看网上有一些人解释这个含义,但是还是感觉不太对,大家有谁知道的话希望能帮忙解答下疑惑,感谢,🙏:链接:https://zhidao.baidu.com/question/917939701567497939.html
ActivityStack#resumeTopActivityInnerLocked
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
}
...
next.completeResumeLocked();
} catch (Exception e) {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
next.finishIfPossible("resume-exception", true /* oomAdj */);
return true;
}
} ...
mStackSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
resumeTopActivityInnerLocked函数会进行activity的pause和下一个activityResume的一些操作,然后启动对应的Activity mStackSupervisor.startSpecificActivity, mStackSupervisor.是ActivityStackSupervisor的实例。
- ActivityStackSupervisor:负责所有ActivityStack的管理。
ActivityStackSupervisor#startSpecificActivity会调用到
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
//1
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
//2
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, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
//3
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
上面的代码中首先创建了一个ClientTransition对象,然后为clientTransition添加了一个callback对象,并将这个对象提交到ClientLifecycleManager中。
- ClientTransaction:保存一系列消息的容器,这些消息可能被发送到客户端,可以用这个对象和客户端交互。
ClientLifecycleManager#scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
...
}
ClientTransaction#schedule的代码如下,
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
其实mClient其实就是
IApplicationThread这个AIDL接口,具体的实现类其实是ActivityThread的内部类ApplicationThread, mClient.scheduleTransaction(this),会去调用app中的ApplicationThread中的scheduleTransaction方法,
- IApplicationThread:是系统进程持有的app进程中ApplicationThread的Binder代理对象。系统进程通过ProcessRecord.IApplicationThread调用app进程相关方法。
- ApplicationThread:ActivityThread的内部类,继承了IApplicationThread.Stub。AMS通过binder代理调用到ApplicationThread中的方法后,通过主线程(ActivityThread中的main方法)中开启的handler消息轮询来通知主线程调用相关方法。主线程的相关生命周期方法的具体实现会委托给Instrumentation类实现,在Instrumentation类中,会调用具体组件的相关生命周期方法。

mClient.scheduleTransaction会回掉客户端的ApplicationThread,
客户端处理
ApplicationThread#scheduleTransaction的代码如下:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
- ActivityThread: 运行在UI线程(主线程)。它管理应用程序进程中主线程的执行、调度和执行activities、broadcasts以及activity manager请求的其他操作。
上面代码中调用了ActivityThread#scheduleTransaction,但是ActivityThread中并没有scheduleTransaction方法的实现,不过ActivityThread是ClientTransactionHandler的子类,所以调用了ClientTransactionHandler#scheduleTransaction方法。
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
- ClientTransactionHandler:定义客户端事务,即ClientTransaction可以在客户端执行的事务的操作。是ActivityThread的父类。
ActivityThread.H会去调用H类中定义的处理消息的handlerMessage方法
ActivityThread#H#handleMessage
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;
TransactionExecutor事务执行器的execute()方法并把ClientTransaction 作为参数,execute方法代码如下:
TransactionExecutor#execute
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
...
//1
executeCallbacks(transaction);
//2
executeLifecycleState(transaction);
...
}
这个函数中主要有两个主要的逻辑,executeCallbacks是执行traction中添加的callback逻辑,executeLifecycleState是执行activity自己的生命周期逻辑,
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
...
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
//1
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
...
}
}
ClientTransactionItem的item变量方法是在上面realStartActivityLocked中构造的LaunchActivityItem对象,
LaunchActivityItem#execute
@Override
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, mAssistToken, mFixedRotationAdjustments);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
execute函数会去调用client的handleLaunchActivity函数,这里的client调用的时候传入的是mTransactionHandler,查看代码可以看到,这个就是ActivithThread对象的引用,因为handler继承了ClientTransactionHandler
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
ActivityThread#handleLaunchActivity函数
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
ActivityThread#performLaunchActivity会加载需要的activity,同时创建所需要的activity实例对象,
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
//加载对应的activity类
java.lang.ClassLoader cl = appContext.getClassLoader();
//创建实例activity对象
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) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
return activity;
}
上面的代码会创建activity的实例,并且调用对应的activityonCreate方法,
Instrumentation#callActivityOnCreate
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
Activity.performCreate会调用到Activity#onCreate函数,
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
}
客户端处理流程图:

到这里activity就走到了自己的onCreate生命周期。android源码中的东西相当复杂,我们在看代码的时候要对主要的流程有一个好的把控,不然最后会迷失在代码的细节中,掌握了流程,后面需要看细节或者修改代码我们也知道从哪里入手。
参考:
https://blog.csdn.net/guojingbu/article/details/117259786
https://blog.csdn.net/yu749942362/article/details/107978083
https://blog.csdn.net/to_perfect/article/details/117754718

1497

被折叠的 条评论
为什么被折叠?



