当前位置:   article > 正文

Activity的启动流程_activity启动流程

activity启动流程

小伙伴们面试的时候是不是被问过Activity的启动流程很多啊。那我们就来看看吧。个人感觉这类文章代码细节太多,反而容易迷失在源码调用之中,从而忽略了Activity启动过程的本质。所以本文就简单地定性地对Activity启动过程进行描述,不会贴上大篇幅的源码。本文是根据Android11.0系统源码讲述的。

冷启动与热启动

Activity启动过程中,一般会牵涉到应用启动的流程。应用启动又分为冷启动和热启动。

  1. 冷启动:点击桌面图标,手机系统不存在该应用进程,这时系统会重新fork一个子进程来加载Application并启动Activity,这个启动方式就是冷启动。
  2. 热启动:应用的热启动比冷启动简单得多,开销也更低。在热启动中,因为系统里已有该应用的进程,所以系统的所有工作就是将您的 Activity 带到前台。 冷启动是应用完全从0开始启动,涉及到更多的内容,所以就应用冷启动的过程展开讨论。

应用启动流程

一般来说,冷启动包括了以下内容:

  1. 启动进程 点击图标发生在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 是获取的什么呢

  1. public static IActivityManager getService() {
  2. 4126 return IActivityManagerSingleton.get();
  3. 4127 }
  4. 4128
  5. 4129 private static final Singleton<IActivityManager> IActivityManagerSingleton =
  6. 4130 new Singleton<IActivityManager>() {
  7. 4131 @Override
  8. 4132 protected IActivityManager create() {
  9. 4133 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
  10. 4134 final IActivityManager am = IActivityManager.Stub.asInterface(b);
  11. 4135 return am;
  12. 4136 }
  13. 4137 };
  14. 4138

 获取的是IActivityManager,通过跨进程进入到ActivityManagerService中的startActivity

/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

  1. @Override
  2. 1210 public final int startActivity(IApplicationThread caller, String callingPackage,
  3. 1211 String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
  4. 1212 String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
  5. 1213 Bundle bOptions) {
  6. 1214 return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
  7. 1215 resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
  8. 1216 UserHandle.getCallingUserId());
  9. 1217 }
  1. private int startActivityAsUser(IApplicationThread caller, String callingPackage,
  2. 1245 @Nullable String callingFeatureId, Intent intent, String resolvedType,
  3. 1246 IBinder resultTo, String resultWho, int requestCode, int startFlags,
  4. 1247 ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
  5. 1248
  6. 1249 final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
  7. 1250
  8. 1251 assertPackageMatchesCallingUid(callingPackage);
  9. 1252 enforceNotIsolatedCaller("startActivityAsUser");
  10. 1253
  11. 1254 if (intent != null && intent.isSandboxActivity(mContext)) {
  12. 1255 SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
  13. 1256 SdkSandboxManagerLocal.class);
  14. 1257 sdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity(
  15. 1258 intent, Binder.getCallingUid(), callingPackage
  16. 1259 );
  17. 1260 }
  18. 1261
  19. 1262 if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
  20. 1263 SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
  21. 1264 SdkSandboxManagerLocal.class);
  22. 1265 if (sdkSandboxManagerLocal == null) {
  23. 1266 throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
  24. 1267 + " an activity from an SDK sandbox uid.");
  25. 1268 }
  26. 1269 sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
  27. 1270 }
  28. 1271
  29. 1272 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
  30. 1273 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
  31. 1274
  32. 1275 // TODO: Switch to user app stacks here.
  33. 1276 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
  34. 1277 .setCaller(caller)
  35. 1278 .setCallingPackage(callingPackage)
  36. 1279 .setCallingFeatureId(callingFeatureId)
  37. 1280 .setResolvedType(resolvedType)
  38. 1281 .setResultTo(resultTo)
  39. 1282 .setResultWho(resultWho)
  40. 1283 .setRequestCode(requestCode)
  41. 1284 .setStartFlags(startFlags)
  42. 1285 .setProfilerInfo(profilerInfo)
  43. 1286 .setActivityOptions(opts)
  44. 1287 .setUserId(userId)
  45. 1288 .execute();
  46. 1289
  47. 1290 }

跳转到/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

执行execute

 然后看executeRequest 中代码

 再看startActivityUnchecked

  1. private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
  2. 1459 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
  3. 1460 int startFlags, ActivityOptions options, Task inTask,
  4. 1461 TaskFragment inTaskFragment, @BalCode int balCode,
  5. 1462 NeededUriGrants intentGrants, int realCallingUid) {
  6. 1463 int result = START_CANCELED;
  7. 1464 final Task startedActivityRootTask;
  8. 1465
  9. 1466 // Create a transition now to record the original intent of actions taken within
  10. 1467 // startActivityInner. Otherwise, logic in startActivityInner could start a different
  11. 1468 // transition based on a sub-action.
  12. 1469 // Only do the create here (and defer requestStart) since startActivityInner might abort.
  13. 1470 final TransitionController transitionController = r.mTransitionController;
  14. 1471 Transition newTransition = transitionController.isShellTransitionsEnabled()
  15. 1472 ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
  16. 1473 RemoteTransition remoteTransition = r.takeRemoteTransition();
  17. 1474 try {
  18. 1475 mService.deferWindowLayout();
  19. 1476 transitionController.collect(r);
  20. 1477 try {
  21. 1478 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
  22. 1479 result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
  23. 1480 startFlags, options, inTask, inTaskFragment, balCode,
  24. 1481 intentGrants, realCallingUid);
  25. 1482 } finally {
  26. 1483 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
  27. 1484 startedActivityRootTask = handleStartResult(r, options, result, newTransition,
  28. 1485 remoteTransition);
  29. 1486 }
  30. 1487 } finally {
  31. 1488 mService.continueWindowLayout();
  32. 1489 }
  33. 1490 postStartActivityProcessing(r, result, startedActivityRootTask);
  34. 1491
  35. 1492 return result;
  36. 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

  1. public static void main(String[] args) {
  2. 7612 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
  3. 7613
  4. 7614 // Install selective syscall interception
  5. 7615 AndroidOs.install();
  6. 7616
  7. 7617 // CloseGuard defaults to true and can be quite spammy. We
  8. 7618 // disable it here, but selectively enable it later (via
  9. 7619 // StrictMode) on debug builds, but using DropBox, not logs.
  10. 7620 CloseGuard.setEnabled(false);
  11. 7621
  12. 7622 Environment.initForCurrentUser();
  13. 7623
  14. 7624 // Make sure TrustedCertificateStore looks in the right place for CA certificates
  15. 7625 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
  16. 7626 TrustedCertificateStore.setDefaultUserDirectory(configDir);
  17. 7627
  18. 7628 // Call per-process mainline module initialization.
  19. 7629 initializeMainlineModules();
  20. 7630
  21. 7631 Process.setArgV0("<pre-initialized>");
  22. 7632
  23. 7633 Looper.prepareMainLooper();
  24. 7634
  25. 7635 // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
  26. 7636 // It will be in the format "seq=114"
  27. 7637 long startSeq = 0;
  28. 7638 if (args != null) {
  29. 7639 for (int i = args.length - 1; i >= 0; --i) {
  30. 7640 if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
  31. 7641 startSeq = Long.parseLong(
  32. 7642 args[i].substring(PROC_START_SEQ_IDENT.length()));
  33. 7643 }
  34. 7644 }
  35. 7645 }
  36. 7646 ActivityThread thread = new ActivityThread();
  37. 7647 thread.attach(false, startSeq);
  38. 7648
  39. 7649 if (sMainThreadHandler == null) {
  40. 7650 sMainThreadHandler = thread.getHandler();
  41. 7651 }
  42. 7652
  43. 7653 if (false) {
  44. 7654 Looper.myLooper().setMessageLogging(new
  45. 7655 LogPrinter(Log.DEBUG, "ActivityThread"));
  46. 7656 }
  47. 7657
  48. 7658 // End of event ActivityThreadMain.
  49. 7659 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  50. 7660 Looper.loop();
  51. 7661
  52. 7662 throw new RuntimeException("Main thread loop unexpectedly exited");
  53. 7663 }
  54. 7664

AMS是通过thread.attah管理新进程中的Activity的

 

其中  final IActivityManager mgr = ActivityManager.getService(); 获取到AMS,然后mgr.attachApplication 添加 ApplicationThread

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/528844
推荐阅读
相关标签
  

闽ICP备14008679号