【Android 14源码分析】Activity启动流程-3
忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
– 服装学院的IT男
本篇已收录于Activity短暂的一生系列
欢迎一起学习讨论Android应用开发或者WMS
V:WJB6995
Q:707409815
正文
由于篇幅原因,整个启动流程分为以下3篇进行分析:
本篇介绍阶段三的逻辑,这部分的分析上篇阶段二的触发点是同级的,也就是在阶段一中 TaskFragment::resumeTopActivity 触发的。
进程是怎么创建的不是当前分析的重点,所以快速过一遍流程。
1 阶段三–触发进程创建
执行pause后会执行 ActivityTaskManagerService::startProcessAsync,最后也是通过 ActivityManagerService来触发启动进程的。
看看AMS这块执行进程创建的调用流程
# ActivityTaskManagerService
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
try {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
+ activity.processName);
}
// 发送消息,启动进程,调用 ActivityManagerInternal::startProcess
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
这里通过 Handler 来完成,ActivityManagerInternal::startProcess 的实现在 ActivityManagerService 的内部类 LocalService 中。
# ActivityManagerService$LocalService
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
// 继续调用
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
null /* sdkSandboxClientAppPackage */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
流程走到 ProcessList::startProcessLocked 。
# ProcessList
boolean startProcessLocked(......) {
......
mService.mProcStartHandler.post(() -> handleProcessStart(
app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
requiredAbi, instructionSet, invokeWith, startSeq));
......
}
private void handleProcessStart(......) {
创建一个用于启动进程的 Runnable 对象
final Runnable startRunnable = () -> {
try { // 调用 startProcess 方法启动进程,并获取启动结果 ProcessStartResult
final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
app.getStartTime());
// 在锁定 ActivityManagerService 后,处理进程启动结果
synchronized (mService) {
// 更新应用的状态,如设置PID,更新生命周期状态等
handleProcessStartedLocked(app, startResult, startSeq);
}
} catch (RuntimeException e) {
......异常处理
}
};
......
}
-
- 通过 ProcessList::startProcess 来启动应用进程
-
- 启动玩之后 ProcessList::handleProcessStartedLocked 会更新应用的状态,如设置PID,更新生命周期状态等
ProcessList::handleProcessStartedLocked 经过几次重载会调用下面的方法
# ProcessList
ActivityManagerService mService = null;
boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
long expectedStartSeq, boolean procAttached) {
......
StringBuilder buf = mStringBuilder;
buf.append("Start proc ");
buf.append(pid);
buf.append(':');
buf.append(app.processName);
buf.append('/');
UserHandle.formatUid(buf, app.getStartUid());
if (app.getIsolatedEntryPoint() != null) {
buf.append(" [");
buf.append(app.getIsolatedEntryPoint());
buf.append("]");
}
buf.append(" for ");
buf.append(app.getHostingRecord().getType());
if (app.getHostingRecord().getName() != null) {
buf.append(" ");
buf.append(app.getHostingRecord().getName());
}
// 输出日志
mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.getStartUid());
......
}
1.1创建进程小结
创建进行逻辑我没深入了解过,所以简单看了下调用逻辑,以 AMS::reportUidInfoMessageLocked 结束的原因是因为其会打印下面的这个创建进程的关键日志:
07-26 19:19:05.477 8737 8782 I ActivityManager: Start proc 19643:com.example.myapplication/u0a198 for next-top-activity {com.example.myapplication/com.example.myapplication.MainActivity}
经常看日志看启动了哪个进程搜的日志就是在这里打印的。
这部分的调用链如下:
ActivityTaskManagerService::startProcessAsync
ActivityManagerService$LocalService::startProcess
ActivityManagerService::startProcessLocked
ProcessList::startProcessLocked
ProcessList::handleProcessStart
ProcessList::startProcess -- 启动进程
ProcessList::handleProcessStartedLocked
ActivityManagerService::reportUidInfoMessageLocked -- 打印日志
2. 阶段三–应用进程创建
进程创建完成后会执行 ActivityThread::main 方法,所以应用端进程创建结束的逻辑从这个方法开始分析。
2.1 应用端处理
# ActivityThread
// ApplicationThread 是 AMS 作为 C 端时,与应用进程通信的方式
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
......
// 主线程Looper
Looper.prepareMainLooper();
......
ActivityThread thread = new ActivityThread();
// 下一步
thread.attach(false, startSeq);
// 主线程Looper
Looper.loop();
}
private void attach(boolean system, long startSeq) {
......
final IActivityManager mgr = ActivityManager.getService();
try {
//重点 *2. 将mAppThread告知AMS,用于AMS与应用进程通信
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
......
}
应用端的调用链比较简单:
ActivityThread::main
Looper::prepareMainLooper
ActivityThread::init
ActivityThread::attach
ActivityManagerService::attachApplication -- 跨进程
Looper::loop
应用进程(电话)创建完毕后,在 main 方法里会执行 attach 就是要将自己的信息告知AMS,毕竟 AMS 是管理模块。
2.2 system_service端处理
system_service 端 ActivityManagerService 知道有进程启动了,这个行为也可能会触发系统组显示逻辑的改变,所以比如也会做响应处理
2.1 调用链
ActivityManagerService::attachApplication
ActivityManagerService::attachApplicationLocked
ActivityThread::bindApplication
ActivityTaskManagerService.LocalService::attachApplication
WindowContainer::forAllRootTasks --- 省略forAllRootTasks等固定堆栈
Task::forAllRootTasks
WindowContainer::forAllActivities
ActivityRecord::forAllActivities
RootWindowContainer.AttachApplicationHelper::test
RootWindowContainer.AttachApplicationHelper::test
ActivityTaskSupervisor::realStartActivityLocked -- 构建LaunchActivityItem
接上一篇知道如果进程启动了 ActivityTaskSupervisor::startSpecificActivity 就会走进去ActivityTaskSupervisor::realStartActivityLocked 。
但是可能会好奇怎么就知道要执行应用 MainActivity 到 onCreate 就一定是在这个方法里呢? 调试方法有很多,比如加 log ,打堆栈,但是对应这个逻辑比较简单的是,需要执行 Activity 启动到 onCreate 的控制在 LaunchActivityItem 中,而 LaunchActivityItem在 framework 的引用除了本身,就只有在 ActivityTaskSupervisor。
2.2 主流程
# ActivityManagerService
// 当应用进程调用attachApplication 执行
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
// 获取 应用进程的信息后执行attachApplicationLocked
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
// 执行
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// 需要启动应用的进程数据
ProcessRecord app;
......
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
// 通过mPidsSelfLocked获取
app = mPidsSelfLocked.get(pid);
}
......
}
......
// 触发ActivityThread::bindApplication 逻辑
if (app.getIsolatedEntryPoint() != null) {
......
} else if (instr2 != null) {
// bindApplication
......
} else {
// 重点* 1. bindApplication
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
}
......
if (!mConstants.mEnableWaitForFinishAttachApplication) {
// 重点* 2.
finishAttachApplicationInner(startSeq, callingUid, pid);
} else {
app.setPendingFinishAttach(true);
}
......
}
ActivityManagerService::finishAttachApplicationInner 是 U 把原来的逻辑提取新增的方法。
# ActivityManagerService
public ActivityTaskManagerInternal mAtmInternal;
private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
......
if (normalMode) {
try {
// 重点 触发构建 LaunchActivityItem 流程
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
......
}
这里是触发 LaunchActivityItem 的流程主线, mAtmInternal是 ATMS 的内部类 LocalService 。
# ActivityTaskManagerService$LocalService
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
......
return mRootWindowContainer.attachApplication(wpc);
......
}
流程来到 RootWindowContainer 预感要开始处理窗口显示逻辑。
# RootWindowContainer
private final AttachApplicationHelper mAttachApplicationHelper = new AttachApplicationHelper();
boolean attachApplication(WindowProcessController app) throws RemoteException {
try {
return mAttachApplicationHelper.process(app);
} finally {
mAttachApplicationHelper.reset();
}
}
# RootWindowContainer
// 实现 Consumer 接口
private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
......
boolean process(WindowProcessController app) throws RemoteException {
mApp = app;
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
// 重点* 调用每个容器的 forAllRootTasks
getChildAt(displayNdx).forAllRootTasks(this);
......
}
......
}
......
}
这里看到传递了“this”,所以 AttachApplicationHelper 必然实现了 Consumer 接口, 直接看其 accept 实现即可。
# RootWindowContainer$AttachApplicationHelper
private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {
......
boolean process(WindowProcessController app) throws RemoteException {
mApp = app;
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
// 重点*1. 调用每个容器的 forAllRootTasks
getChildAt(displayNdx).forAllRootTasks(this);
......
}
......
}
@Override
public void accept(Task rootTask) {
......
if (rootTask.getVisibility(null /* starting */)
== TASK_FRAGMENT_VISIBILITY_INVISIBLE) {
// 如果Task 不可见则不需要处理
return;
}
// 执行 topRunningActivity
mTop = rootTask.topRunningActivity();
// 重点*2. 执行accept 让容器下的每个 ActivityRecord 执行 test
rootTask.forAllActivities(this);
}
@Override
public boolean test(ActivityRecord r) {
// 判断 ActivityRecord 是否满足需要启动条件
if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard
|| r.app != null || mApp.mUid != r.info.applicationInfo.uid
|| !mApp.mName.equals(r.processName)) {
return false;
}
try {
// 重点*3. 执行 realStartActivityLocked 尝试实际启动 Activity
if (mTaskSupervisor.realStartActivityLocked(r, mApp,
mTop == r && r.getTask().canBeResumed(r) /* andResume */,
true /* checkConfig */)) {
mHasActivityStarted = true;
}
} catch (RemoteException e) {
......
}
return false;
}
}
这部分的逻辑也就是一路执行,比较疑惑的点也许是进入 AttachApplicationHelper::proces 方法后的几个 Lambda 表达式容易绕晕。
简单梳理一下,首先是从 RootWindowContainer 开始执行的,目的就是想要执行到所有 ActivityRecord 然后判断一下它的情况是不是需要启动对应的 Activity 。
-
- AttachApplicationHelper::proces 里的 “getChildAt” 对应的是每个屏幕,也就是 DisplayContent ,然后再遍历其下的每个 RootTask ,让其执行 accept 函数
-
- AttachApplicationHelper::accept 目前是对象是 Task ,准确的说是 RootTask 。如果这个 Task 是可见的,则又开始遍历其下的所有 ActivityRecord ,让其执行 test 函数
-
- AttachApplicationHelper::test 方法是真正干活的地方,所有一堆条件判断这个 ActivityRecord 是否满足
- r.finishing:活动是否正在结束
- !r.showToCurrentUser() :活动是否对当前用户可见
- !r.visibleIgnoringKeyguard :活动是否可见,即使有屏幕保护器
- r.app != null :活动的应用程序是否已经存在
- mApp.mUid != r.info.applicationInfo.uid :应用程序的UID是否与预期的不同
- !mApp.mName.equals(r.processName):应用程序的名称是否与活动的进程名称不同
感觉比较重要的就是前面3个条件,这个 ActivityRecord 是不是需要显示给用户,如果需要则执行 ActivityTaskSupervisor::realStartActivityLocked 试图启动 Activity 。
3. 阶段三总结
阶段三的流程相对来逻辑简单一些,知道个调用链就好,流程目的就是执行 ActivityTaskSupervisor::realStartActivityLocked 。
这部分的堆栈如下图:
加上应用端的调用链,完成调用链如下:
ActivityThread::main
Looper::prepareMainLooper
ActivityThread::init
ActivityThread::attach
ActivityManagerService::attachApplication -- 跨进程
ActivityManagerService::attachApplicationLocked
ActivityThread::bindApplication
ActivityManagerService::finishAttachApplicationInner
ActivityTaskManagerService$LocalService::attachApplication
RootWindowContainer::attachApplication
RootWindowContainer$AttachApplicationHelper::process -- 开始遍历
WindowContainer::forAllRootTasks --- 省略forAllRootTasks等固定堆栈
Task::forAllRootTasks -- 1. 遍历所有root Task
RootWindowContainer$AttachApplicationHelper::accept -- 1.1 root Task执行accept
WindowContainer::forAllActivities -- 2. 遍历下面的所有ActivityRecord
ActivityRecord::forAllActivities
RootWindowContainer$AttachApplicationHelper::test -- 2.1 ActivityRecord执行test
ActivityTaskSupervisor::realStartActivityLocked -- 试图启动Activity
Looper::loop
对应时序图:
大概流程图如下:
这一阶段主要就是应用进程启动后,试图拉起对应的 Activity ,能不能启动的条件就是没有正在 pause 的 Activity 了。
主要逻辑就是触发 ActivityTaskSupervisor::realStartActivityLocked
4. 阶段四–真正启动Activity
阶段四其实就是触发应用端创建 Activity 。
4.1 realStartActivityLocked
这个方法是要真去触发 Activity 启动的,根据前面的流程图,阶段二,三的最终就是想执行到这个方法里面,来触发 Activity 启动。
这个方法的最终目的就是通过事务执行 LaunchActivityItem 和 PauseActivityItem ,也就是会触发应用端 TargetActivity 启动,并执行生命周期到 onCreate 和 onResume 。
# ActivityTaskSupervisor
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 重点* 1. 判断是否执行完了pause
if (!mRootWindowContainer.allPausedActivitiesComplete()) {
// While there are activities pausing we skipping starting any new activities until
// pauses are complete. NOTE: that we also do this for activities that are starting in
// the paused state because they will first be resumed then paused on the client side.
// 如果还有Activity没完成pause,则打印日志并return
ProtoLog.v(WM_DEBUG_STATES,
"realStartActivityLocked: Skipping start of r=%s some activities pausing...",
r);
return false;
}
// 重点* 2. 表示ActivityRecord已连接到相应的进程
r.setProcess(proc);
......
// event日志: wm_restart_activity
EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
task.mTaskId, r.shortComponentName);
......
// 重点* 3.1 创建事务,用于Activity启动
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);
final boolean isTransitionForward = r.isTransitionForward();
// 获取Activity所在 TaskFragment Token
final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
// 重点* 3.2 将构建的 LaunchActivityItem 添加到 clientTransaction 中
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.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
// 重点* 3.3 设置预期的最终状态为 ResumeActivityItem
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
// Resume逻辑,启动走的这。 表示需要执行到onCreate
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
// Pause 逻辑
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 重点* 3.4 执行事务
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
}
根据代码的标注解释:
-
- 根据注释,如果有 Activity 正在 pause 则不允许任何 Activity 启动。换句话说就是想要启动一个 Activity 必须其他的 Activity 需要 pause 的都完成了 pause 流程
-
- 对应上一篇提到的 ActivityRecord::attachedToProcess 方法如果需要返回 true ,则必须在这里执行 setProcess 方法,否则 ActivityRecord 下的 app 变量就是 null
-
- 这里就是开始真正执行启动 Activity 的地方了,是通过事务执行的,分为以下几步
- 3.1 构建一个事务
- 3.2 设置 LaunchActivityItem ,这一步会将 Activity 的生命周期执行到 onCreate
- 3.3 设置 ResumeActivityItem ,这一步会将 Activity 的生命周期执行到 onResume
- 3.4 执行事务
后续逻辑就是在应用端执行 Activity 的创建,以及生命周期处理了,这部分本篇大概看一遍流程,以分析到 Activity 的创建为止。
4.2 创建Activity
这部分的调用链如下:
LaunchActivityItem::execute
ActivityThread::handleLaunchActivity
ActivityThread::performLaunchActivity
Instrumentation::newActivity -- 创建Activity
Activity::attach -- 处理Window相关
Window::init
Window::setWindowManager
Instrumentation::callActivityOnCreate -- onCreate流程
Activity::performCreate
Activity::onCreate --over
时序图图下:
接下来看 LaunchActivityItem::execute
# 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, mActivityOptions, mIsForward, mProfilerInfo,
client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
mTaskFragmentToken);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
这里的 client 是 ClientTransactionHandler 类型, 而 ActivityThread 是 ClientTransactionHandler 子类。
重点是这边创建了 ActivityClientRecord ,第一个参数就是我们要找的token
逻辑来到应用进程 ActivityThread
# ActivityThread
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
final Activity a = performLaunchActivity(r, customIntent);
......
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
try {
// 重点* 1. 通过Instrumentation 反射创建Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
}
try {
......
// 重点* 2. 执行 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.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
......
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
重点* 3. onCreate流程
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
......
}
这里有3个重点:
-
- Activity 是通过反射创建的。 到这里其实 Activity 启动流程基本分析完了
-
- 执行 Activity::attach 。这里会触发创建 Window
-
- 触发 Activity::onCreate
Activity 已经创建好了,那就剩下 onCreate 了。
# Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
// onCreate流程
activity.performCreate(icicle);
postPerformCreate(activity);
}
# Activity
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
// 执行onCreate
onCreate(icicle);
}
......
}
写过应用的都知道,默认都是一个参数的onCreate。
至此,Activity 启动流程分析完毕。
在 ActivityTaskSupervisor::realStartActivityLocked 方法看到给事务加了个 ResumeActivityItem , 因为 LaunchActivityItem 只是创建,但是创建完成后,需要执行到对应的生命周期。
正常情况都是希望执行到onResume,所以会设置 ResumeActivityItem 。
4.3 阶段四小结
无论是阶段二还是阶段三触发了 ActivityTaskSupervisor::realStartActivityLocked 方法,并且还满足启动 Activity 条件,则会触发应用端进程 Activity 的创建和生命周期的执行。
原文地址:https://blog.csdn.net/qq_38679144/article/details/142641984
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!