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 是获取的什么呢

  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

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值