Android Framework学习——安卓进程启动流程(Android 13)

提示:本文仅作个人学习记录,禁止转载
本文参考:袁神的文章,理解Android进程创建流程


1,前言

进程是作为应用程序容器存在的,每个应用启动前需要先创建一个进程,进程是由Zygote进程孵化来的,它拥有独立的资源空间,用来运行四大组件,大部分应用运行在一个进程上,部分应用如微信、支付宝等运行在多个进程上,比如微信小程序就是一个子进程。

2,简略步骤

引用袁神的流程图
1,发起进程:应用可以从桌面或其他应用内启动,根据启动起点不同,发起进程可以是Launcher所在进程,也可以是某个应用所在进程。发起进程先通过binder给system_server进程发消息;
2,system_server进程:通过Socket向Zygote进程发送创建新进程的请求;
3,Zygote进程:在执行ZygoteInit.main()后进入runSelectLoop()循环内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,最终fork出新的应用进程;
4,新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。

3,代码走读

3.1,提要,从系统启动末尾开始

结合上一篇安卓系统启动流程,从ActivityTaskSupervisor(/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java)对象调用startSpecificActivity()方法开始。

1034      void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
   
			  	//省略部分代码...
1040          if (wpc != null && wpc.hasThread()) {
   
1041              try {
   
1042                  realStartActivityLocked(r, wpc, andResume, checkConfig);
1043                  return;
1044              } catch (RemoteException e) {
   
1045                  Slog.w(TAG, "Exception when starting activity "
1046                          + r.intent.getComponent().flattenToShortString(), e);
1047              } 	
			  //省略部分代码...
1060          mService.startProcessAsync(r, knownToBeDead, isTop,
1061                  isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
1062                          : HostingRecord.HOSTING_TYPE_ACTIVITY);
1063      }

如上代码块,在1040行判断,若进程不存在则执行1060行逻辑,通过mService(ActivityTaskManagerService)调用startProcessAsync()方法创建进程,进入此方法。

4717      void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
4718              String hostingType) {
   
4719          try {
   
4720              if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
   
4721                  Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
4722                          + activity.processName);
4723              }
4724              // Post message to start process to avoid possible deadlock of calling into AMS with the
4725              // ATMS lock held.
4726              final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
4727                      mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
4728                      isTop, hostingType, activity.intent.getComponent());
4729              mH.sendMessage(m);
4730          } finally {
   
4731              Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
4732          }
4733      }

如上代码块,4724行注释所示,通过发送一个消息来创建进程防止持有ATMS锁时调用AMS可能出现的死锁。这个代码块中我们关注下创建消息时的第一个参数ActivityManagerInternal::startProcess,即ActivityManagerInternal类(/frameworks/base/core/java/android/app/)的startProcess()方法执行的结果。
进入此方法。

482      /** Starts a given process. */
483      public abstract void startProcess(String processName, ApplicationInfo info,
484              boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);

可以看到这是一个抽象方法,注释说明启动一个给定的进程。我们看看它的具体实现。

16341      public final class LocalService extends ActivityManagerInternal
16342              implements ActivityManagerLocal {
   

			  //省略部分代码...

17165          @Override
17166          public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
17167                  boolean isTop, String hostingType, ComponentName hostingName) {
   
17168              try {
   
17169                  if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
   
17170                      Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
17171                              + processName);
17172                  }
17173                  synchronized (ActivityManagerService.this) {
   
17174                      // If the process is known as top app, set a hint so when the process is
17175                      // started, the top priority can be applied immediately to avoid cpu being
17176                      // preempted by other processes before attaching the process of top app.
17177                      startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
17178                              new HostingRecord(hostingType, hostingName, isTop),
17179                              ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
17180                              false /* isolated */);
17181                  }
17182              } finally {
   
17183                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
17184              }
17185          }

从上段代码块可以看出,LocalService是ActivityManagerService(/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)的内部类,继承了ActivityManagerInternal重写了startProcess()方法。此方法内重点看17177行startProcessLocked()方法,展开这个方法。

2837      final ProcessRecord startProcessLocked(String processName,
2838              ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2839              HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
2840              boolean isolated) {
   
2841          return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
2842                  hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
2843                  false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
2844                  null /* sdkSandboxClientAppPackage */,
2845                  null /* ABI override */, null /* entryPoint */,
2846                  null /* entryPointArgs */, null /* crashHandler */);
2847      }

上一段代码最终返回mProcessList调用startProcessLocked()方法返回值,mProcessList是ProcessList对象(/frameworks/base/services/core/java/com/android/server/am/ProcessList.java),如下所示,用来管理进程。

776      /**
777       * Process management.
778       */
779      final ProcessList mProcessList;

进入startProcessLocked()方法

1626      /**
1627       * @return {@code true} if process start is successful, false otherwise.
1628       */
1629      @GuardedBy("mService")
1630      boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
1631              int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
1632              String abiOverride) {
   

				  //省略部分代码...
				  //进程存在的情况不创建:比如存在一个application记录;调用进程认为它依然存活;它已被分配一个pid,正在启动或已经启动。

1879              return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
1880                      runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
1881                      instructionSet, invokeWith, startUptime, startElapsedTime);
1882          } catch (RuntimeException e) {
   
1883              Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
1891              mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1892                      false, false, true, false, false, app.userId, "start failure");
1893              return false;
1894          }
1895      }

接下来继续进入1879行startProcessLocked()方法。

1899      boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
1900              int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
1901              String seInfo, String requiredAbi, String instructionSet, String invokeWith,
1902              long startUptime, long startElapsedTime) {
   
			  //省略部分代码...
			  //默认异步启动
1928          if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
   
1929              if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
1930                      "Posting procStart msg for " + app.toShortString());
1931              mService.mProcStartHandler.post(() -> handleProcessStart(
1932                      app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
1933                      requiredAbi, instructionSet, invokeWith, startSeq));
1934              return true;
1935          } else {
   
1936              try {
   
1937                  final Process.ProcessStartResult startResult = startProcess(hostingRecord,
1938                          entryPoint, app,
1939                          uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
1940                          requiredAbi, instructionSet, invokeWith, startUptime);
1941                  handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
1942                          startSeq, false);
1943              } catch (RuntimeException e) {
   
1944                  Slog.e(ActivityManagerService.TAG, "Failure starting process "
1945                          + app.processName, e);
1946                  app.setPendingStart(false);
1947                  mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
1948                          false, false, true, false, false, app.userId, "start failure");
1949              }
1950              return app.getPid() > 0;
1951          }
1952      }

如上代码块中可以看出,默认异步启动最后调用1937行startProcess()方法,进入此方法。

2183      private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
2184              ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
2185              int mountExternal, String seInfo, String requiredAbi, String instructionSet,
2186              String invokeWith, long startTime) {
   

			  //省略部分代码...
			  //hostingRecord初始化为null,会进入最后一个else判断
2279              if (hostingRecord.usesWebviewZygote()) {
   
			  //省略部分代码...
2298              } else {
   
2299                  regularZygote = true;
2300                  startResult = Process.start(entryPoint,
2301                          app.processName, uid, uid, gids, runtimeFlags, mountExternal,
2302                          app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
2303                          app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
2304                          isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
2305                          allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
2306                          new String[]{
   PROC_START_SEQ_IDENT + app.getStartSeq()});
2307              }
2329      }

如上代码块中,hostingRecord初始化为null,会进入2298行最后一个else判断,调用Process(/frameworks/base/core/java/android/os/Process.java)的start()方法。

3.2,system_server发起请求

712      public static ProcessStartResult start(@NonNull final String processClass,
713                                             @Nullable final String niceName,
714                                             int uid, int gid, @Nullable int[] gids,
715                                             int runtimeFlags,
716                                             int mountExternal,
717                                             int targetSdkVersion,
718                                             @Nullable String seInfo,
719                                             @NonNull String abi,
720                                             @Nullable String instructionSet,
721                                             @Nullable String appDataDir,
722                                             @Nullable String invokeWith,
723                                             @Nullable String packageName,
724                                             int zygotePolicyFlags,
725                                             boolean isTopApp,
726                                             @Nullable long[] disabledCompatChanges,
727                                             @Nullable Map<String, Pair<String, Long>>
728                                                     pkgDataInfoMap,
729                                             @Nullable Map<String, Pair<String, Long>>
730                                                     whitelistedDataInfoMap,
731                                             boolean bindMountAppsData,
732                                             boolean bindMountAppStorageDirs,
733                                             @Nullable String[] zygoteArgs) {
   
734          return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
735                      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
736                      abi, instructionSet, appDataDir, invokeWith, packageName,
737                      zygotePolicyFlags, isTopApp, disabledCompatChanges,
738                      pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
739                      bindMountAppStorageDirs, zygoteArgs);
740      }

ZYGOTE_PROCESS为ZygoteProcess(/frameworks/base/core/java/android/os/ZygoteProcess.java) 对象,接着进入734行它的start()方法

345
  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Framework 可以通过注册监听器来监听进程启动事件。具步骤如下: 1. 创建一个 BroadcastReceiver 类,重写 onReceive() 方法,在方法中处理进程启动事件。 2. 在 AndroidManifest.xml 文件中注册 BroadcastReceiver。 3. 在 BroadcastReceiver 中使用 IntentFilter 监听 ACTION_PACKAGE_ADDED 和 ACTION_PACKAGE_REPLACED 两个系统广播,这两个广播会在应用程序安装或更新时触发。 4. 在 onReceive() 方法中获取 Intent 对象,通过 Intent 对象获取包名信息,即可得知进程已经启动。 以下是一个简单的例子: ``` public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intent.ACTION_PACKAGE_ADDED) || action.equals(Intent.ACTION_PACKAGE_REPLACED)) { String packageName = intent.getData().getSchemeSpecificPart(); Log.d("MyBroadcastReceiver", "Package added/replaced: " + packageName); // 在这里处理进程启动事件 } } } ``` 在 AndroidManifest.xml 文件中注册 BroadcastReceiver: ``` <receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.PACKAGE_ADDED" /> <action android:name="android.intent.action.PACKAGE_REPLACED" /> <data android:scheme="package" /> </intent-filter> </receiver> ``` 注意:需要在 AndroidManifest.xml 文件中声明 RECEIVE_BOOT_COMPLETED 权限,才能够在设备启动时接收广播。 ``` <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值