小伙伴们面试的时候是不是被问过Activity的启动流程很多啊。那我们就来看看吧。个人感觉这类文章代码细节太多,反而容易迷失在源码调用之中,从而忽略了Activity启动过程的本质。所以本文就简单地定性地对Activity启动过程进行描述,不会贴上大篇幅的源码。本文是根据Android11.0系统源码讲述的。
冷启动与热启动
Activity启动过程中,一般会牵涉到应用启动的流程。应用启动又分为冷启动和热启动。
- 冷启动:点击桌面图标,手机系统不存在该应用进程,这时系统会重新fork一个子进程来加载Application并启动Activity,这个启动方式就是冷启动。
- 热启动:应用的热启动比冷启动简单得多,开销也更低。在热启动中,因为系统里已有该应用的进程,所以系统的所有工作就是将您的 Activity 带到前台。 冷启动是应用完全从0开始启动,涉及到更多的内容,所以就应用冷启动的过程展开讨论。
应用启动流程
一般来说,冷启动包括了以下内容:
- 启动进程 点击图标发生在Launcher应用的进程,startActivity()函数最终调用的是Instrumentation中execStartActivity
/frameworks/base/core/java/android/app/Activity.java
startActivity
调用的是startActivityForResult
startActivityForResult
调用的是Instrumentation 里面的
/frameworks/base/core/java/android/app/Instrumentation.java
这个圈起来的地方android9.0以及9.0以前是这样调用的,直接调用的是AMS的startActivity
9.0之后是这样调用的,调用的是ATM的startActivity
ActivityTaskManager.getService 是获取的什么呢
public static IActivityManager getService() {
4126 return IActivityManagerSingleton.get();
4127 }
4128
4129 private static final Singleton<IActivityManager> IActivityManagerSingleton =
4130 new Singleton<IActivityManager>() {
4131 @Override
4132 protected IActivityManager create() {
4133 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
4134 final IActivityManager am = IActivityManager.Stub.asInterface(b);
4135 return am;
4136 }
4137 };
4138
获取的是IActivityManager,通过跨进程进入到ActivityManagerService中的startActivity
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
1210 public final int startActivity(IApplicationThread caller, String callingPackage,
1211 String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
1212 String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
1213 Bundle bOptions) {
1214 return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
1215 resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
1216 UserHandle.getCallingUserId());
1217 }
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
1245 @Nullable String callingFeatureId, Intent intent, String resolvedType,
1246 IBinder resultTo, String resultWho, int requestCode, int startFlags,
1247 ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
1248
1249 final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
1250
1251 assertPackageMatchesCallingUid(callingPackage);
1252 enforceNotIsolatedCaller("startActivityAsUser");
1253
1254 if (intent != null && intent.isSandboxActivity(mContext)) {
1255 SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
1256 SdkSandboxManagerLocal.class);
1257 sdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity(
1258 intent, Binder.getCallingUid(), callingPackage
1259 );
1260 }
1261
1262 if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
1263 SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
1264 SdkSandboxManagerLocal.class);
1265 if (sdkSandboxManagerLocal == null) {
1266 throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
1267 + " an activity from an SDK sandbox uid.");
1268 }
1269 sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
1270 }
1271
1272 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
1273 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
1274
1275 // TODO: Switch to user app stacks here.
1276 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
1277 .setCaller(caller)
1278 .setCallingPackage(callingPackage)
1279 .setCallingFeatureId(callingFeatureId)
1280 .setResolvedType(resolvedType)
1281 .setResultTo(resultTo)
1282 .setResultWho(resultWho)
1283 .setRequestCode(requestCode)
1284 .setStartFlags(startFlags)
1285 .setProfilerInfo(profilerInfo)
1286 .setActivityOptions(opts)
1287 .setUserId(userId)
1288 .execute();
1289
1290 }
跳转到/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
执行execute
然后看executeRequest 中代码
再看startActivityUnchecked
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1459 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1460 int startFlags, ActivityOptions options, Task inTask,
1461 TaskFragment inTaskFragment, @BalCode int balCode,
1462 NeededUriGrants intentGrants, int realCallingUid) {
1463 int result = START_CANCELED;
1464 final Task startedActivityRootTask;
1465
1466 // Create a transition now to record the original intent of actions taken within
1467 // startActivityInner. Otherwise, logic in startActivityInner could start a different
1468 // transition based on a sub-action.
1469 // Only do the create here (and defer requestStart) since startActivityInner might abort.
1470 final TransitionController transitionController = r.mTransitionController;
1471 Transition newTransition = transitionController.isShellTransitionsEnabled()
1472 ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
1473 RemoteTransition remoteTransition = r.takeRemoteTransition();
1474 try {
1475 mService.deferWindowLayout();
1476 transitionController.collect(r);
1477 try {
1478 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
1479 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
1480 startFlags, options, inTask, inTaskFragment, balCode,
1481 intentGrants, realCallingUid);
1482 } finally {
1483 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1484 startedActivityRootTask = handleStartResult(r, options, result, newTransition,
1485 remoteTransition);
1486 }
1487 } finally {
1488 mService.continueWindowLayout();
1489 }
1490 postStartActivityProcessing(r, result, startedActivityRootTask);
1491
1492 return result;
1493 }
继续看startActivityInner,如图红色框标志的代码
跳转到 frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
看resumeFocusedTasksTopActivities
resumeTopActivityUnCheckedLocked
接着到 /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java 中resumeTopActivityUnCheckedLocked ,调用红色边框线内代码
resumeTopActivityInnerLocked
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
判断如果进程存在,执行realStartActivityLocked;进程不存在,执行mService.startProcessAsync。这样就回到了开头我们说的冷启动,就会发送请求给Zygote进程,fork出新进程。
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
跳转到ActivityManagerService中的startProcess
然后接着看startProcessLocked
跳转到 /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
中startProcessLocked,执行如下代码
startProcess中执行的是Process start
ZYGOT_PROCESS start 调用的是
/frameworks/base/core/java/android/os/ZygoteProcess.java 里的start
startViaZygote:
看第一个参数openZygoteSocketIfNeeded,
调用的attemptConnectionToPrimaryZygote
connect:
创建了Socket,然后连接zygote
回过头来看startViaZygote这个方法,最后返回的是
然后调用attemptUsapSendArgsAndGetResult
usapWriter.write 写数据,usapReader.read读数据,完成AMS和Zygote之间的通讯。
Zygote是如何创建进程的呢,其实是和system_server创建进程一样的,最终执行的是ActivityThread中的main方法
/frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
7612 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
7613
7614 // Install selective syscall interception
7615 AndroidOs.install();
7616
7617 // CloseGuard defaults to true and can be quite spammy. We
7618 // disable it here, but selectively enable it later (via
7619 // StrictMode) on debug builds, but using DropBox, not logs.
7620 CloseGuard.setEnabled(false);
7621
7622 Environment.initForCurrentUser();
7623
7624 // Make sure TrustedCertificateStore looks in the right place for CA certificates
7625 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
7626 TrustedCertificateStore.setDefaultUserDirectory(configDir);
7627
7628 // Call per-process mainline module initialization.
7629 initializeMainlineModules();
7630
7631 Process.setArgV0("<pre-initialized>");
7632
7633 Looper.prepareMainLooper();
7634
7635 // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
7636 // It will be in the format "seq=114"
7637 long startSeq = 0;
7638 if (args != null) {
7639 for (int i = args.length - 1; i >= 0; --i) {
7640 if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
7641 startSeq = Long.parseLong(
7642 args[i].substring(PROC_START_SEQ_IDENT.length()));
7643 }
7644 }
7645 }
7646 ActivityThread thread = new ActivityThread();
7647 thread.attach(false, startSeq);
7648
7649 if (sMainThreadHandler == null) {
7650 sMainThreadHandler = thread.getHandler();
7651 }
7652
7653 if (false) {
7654 Looper.myLooper().setMessageLogging(new
7655 LogPrinter(Log.DEBUG, "ActivityThread"));
7656 }
7657
7658 // End of event ActivityThreadMain.
7659 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7660 Looper.loop();
7661
7662 throw new RuntimeException("Main thread loop unexpectedly exited");
7663 }
7664
AMS是通过thread.attah管理新进程中的Activity的
其中 final IActivityManager mgr = ActivityManager.getService(); 获取到AMS,然后mgr.attachApplication 添加 ApplicationThread