经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android?应用程序的启动流程示例详解
来源:jb51  时间:2023/3/31 8:57:38  对本文有异议

应用进程的启动流程

本文基于Android 11,主要分析应用程序的启动流程,会直接定位到ActivityStackSupervisor.startSpecificActivity函数开始,因为该函数前面的内容主要在Activity的启动流程中,可以通过这部分的文章来阅读。

看源码流程,需要戒骄戒躁,心态好。配合源码使用,建议先收藏,夜深人静,心血来潮再看。

通过分析应用进程的启动流程,可以得到:

  • 在Framework层,现在不止有AMS负责请求Zygote进程创建新进程,还有ATMS、ActivityStarter、ActivityTaskManger、ActivityTaskS在协助分担一些参数和逻辑的检查。
  • 每个进程都是通过fork Zygote进程而来,且获得Java虚拟机。也就是说每一个应用进程都有自己的虚拟机。
  • 应用进程是通过Soket去请求Zygote进程fork自己的。
  • 每个进程都有自己的Binder线程池用于IPC。
  • 每个应用进程的主线程在ActivityThread,其main函数会创建消息循环机制。

1、ActivityStackSupervisor.startSpecificActivity

ATMS有一个ProcessMap<WindowProcessController>类型的mProcessNames ,用于存储封装了已启动进程信息ProcessRecord和窗口信息Windows的WindowProcessController实例。WindowProcessController用于协调ActivityManger管理ProcessReocrd和WindwManger管理WIndow和Activity的关系。

  1. void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
  2. // Is this activity's application already running?
  3. final WindowProcessController wpc =
  4. mService.getProcessController(r.processName, r.info.applicationInfo.uid);
  5. boolean knownToBeDead = false;
  6. if (wpc != null && wpc.hasThread()) {
  7. realStartActivityLocked(r, wpc, andResume, checkConfig);
  8. return;
  9. ...
  10. knownToBeDead = true;
  11. }
  12. r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
  13. final boolean isTop = andResume && r.isTopRunningActivity();
  14. mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
  15. }

这里的mService是ActivityTaskManagerService的实例,通过getProcessController函数获得当前wpc对象,判断当前启动应用进程是否启动wpc != null && wpc.hasThread(),如果条件成立,则开始真正启动一个未启动过的Activity,通过realStartActivityLocked;条件不成立,则调用mService的startProcessAsync启动当前Activity的所在的进程。即startSpecificActivity函数是启动进程和启动Activity的一个分界点。

2、ATMS.startProcessAsync

PooledLambda.obtainMessage函数是Lambda的调用方式,表示调用ActivityManagerInternal的startProcess函数,后续则是其参数。并返回一个Message对象,发给Handler类型的mH。

  1. void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
  2. String hostingType) {
  3. final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
  4. mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
  5. isTop, hostingType, activity.intent.getComponent());
  6. mH.sendMessage(m);
  7. }

抽象类ActivityManagerInternal的继承类定义在ActivityManagerService的内部类LocalService。

  1. public final class LocalService extends ActivityManagerInternal

3、LocalService.startProcess

  1. @Override
  2. public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
  3. boolean isTop, String hostingType, ComponentName hostingName) {
  4. startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
  5. new HostingRecord(hostingType, hostingName, isTop),
  6. ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
  7. false /* isolated */, true /* keepIfLarge */);
  8. }

4、startProcessLocked函数

  1. final ProcessRecord startProcessLocked(String processName,
  2. ApplicationInfo info, boolean knownToBeDead, int intentFlags,
  3. HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
  4. boolean isolated, boolean keepIfLarge) {
  5. return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
  6. hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
  7. keepIfLarge, null /* ABI override */, null /* entryPoint */,
  8. null /* entryPointArgs */, null /* crashHandler */);
  9. }

5、ProcessList.startProcessLocked

ProcessList类的startProcessLocked函数,有几个重载函数,第一个调用。

在 !isolated,判断了启动IntentFlag是否后台运行,是的话,直接拒绝。否则清理AMS中发生过Crash的进程(当前应用)。

分析一:创立当前应用进程的描述ProcessRecord。

判断当前系统是否启动完毕,未启动完毕,将进程信息缓存到AMS的mProcessesOnHold中。

分析二:调用了另外一个重载函数。

  1. final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
  2. boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
  3. int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
  4. boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
  5. Runnable crashHandler) {
  6. long startTime = SystemClock.uptimeMillis();
  7. ProcessRecord app;
  8. //isolated传递进来是false,
  9. if (!isolated) {
  10. //从mProcessNames缓存获取,由于是首次创建,null
  11. app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
  12. checkSlow(startTime, "startProcess: after getProcessRecord");
  13. //判断要启动进程是否后台运行,直接return null
  14. if ((intentFlags &amp; Intent.FLAG_FROM_BACKGROUND) != 0) {
  15. if (mService.mAppErrors.isBadProcessLocked(info)) {
  16. return null;
  17. }
  18. } else {
  19. //重置进程的crash状态,使其处于正常状态
  20. mService.mAppErrors.resetProcessCrashTimeLocked(info);
  21. if (mService.mAppErrors.isBadProcessLocked(info)) {
  22. mService.mAppErrors.clearBadProcessLocked(info);
  23. if (app != null) {
  24. app.bad = false;
  25. }
  26. }
  27. }
  28. } else {
  29. app = null;
  30. }
  31. ProcessRecord precedence = null;
  32. if (app != null &amp;&amp; app.pid &gt; 0) {
  33. if ((!knownToBeDead &amp;&amp; !app.killed) || app.thread == null) {
  34. app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
  35. return app;
  36. }
  37. ProcessList.killProcessGroup(app.uid, app.pid);
  38. precedence = app;
  39. app = null;
  40. }
  41. if (app == null) {
  42. // 分析一、创建新的应用进程描述ProcessRocrd
  43. //内部会将自己添加到mProcessNames中
  44. app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
  45. if (app == null) {
  46. return null;
  47. }
  48. //此时三者都是null
  49. app.crashHandler = crashHandler;
  50. app.isolatedEntryPoint = entryPoint;
  51. app.isolatedEntryPointArgs = entryPointArgs;
  52. if (precedence != null) {
  53. app.mPrecedence = precedence;
  54. precedence.mSuccessor = app;
  55. }
  56. } else {
  57. app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
  58. }
  59. // If the system is not ready yet, then hold off on starting this
  60. // process until it is.
  61. if (!mService.mProcessesReady
  62. &amp;&amp; !mService.isAllowedWhileBooting(info)
  63. &amp;&amp; !allowWhileBooting) {
  64. if (!mService.mProcessesOnHold.contains(app)) {
  65. mService.mProcessesOnHold.add(app);
  66. }
  67. if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
  68. "System not ready, putting on hold: " + app);
  69. checkSlow(startTime, "startProcess: returning with proc on hold");
  70. return app;
  71. }
  72. 分析二:
  73. final boolean success =
  74. startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
  75. checkSlow(startTime, "startProcess: done starting proc!");
  76. return success ? app : null;
  77. }

6、ProcessList.startProcessLocked重载

再次调用另外一个重载函数。

  1. final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
  2. int zygotePolicyFlags, String abiOverride) {
  3. return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
  4. false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
  5. false /* mountExtStorageFull */, abiOverride);
  6. }

重载函数,这个重载函数处理逻辑很长,主要给前面创建的ProcessRecord类型的app设置各种属性。例如外部存储挂载模式,应用进程运行模式,abi架构等等,其中包括最重要一点就是分析一,确定要启动进程的的类名:android.app.ActivityThread。分析二,继续调用重载函数。

  1. boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
  2. int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
  3. boolean mountExtStorageFull, String abiOverride) {
  4. ...
  5. app.gids = gids;
  6. app.setRequiredAbi(requiredAbi);
  7. app.instructionSet = instructionSet;
  8. final String seInfo = app.info.seInfo
  9. + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
  10. //分析一:确定要启动应用程序的类名
  11. final String entryPoint = "android.app.ActivityThread";
  12. //分析二:调用另外一个重载函数
  13. return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
  14. runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
  15. instructionSet, invokeWith, startTime);
  16. } catch (RuntimeException e) {
  17. ...
  18. }
  19. }

重载函数:也是设置一些属性,然后调用startProcess函数。

  1. boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
  2. int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
  3. String seInfo, String requiredAbi, String instructionSet, String invokeWith,
  4. long startTime) {
  5. ...
  6. final Process.ProcessStartResult startResult = startProcess(hostingRecord,
  7. entryPoint, app,
  8. uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
  9. requiredAbi, instructionSet, invokeWith, startTime);
  10. handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
  11. startSeq, false);
  12. ...
  13. }
  14. }

7、ProcessList.startProcess

ProcessList类的startProcess函数会根据hostingRecord属性mHostingZygote判断走不同的创建分支,前面创建使用默认值,所以走了else分支。通过 Process.start函数创建新的应用进程。

Process.start的一路调用:

  1. Process.start=&gt;ZygoteProcess.start=&gt;ZygoteState.start=&gt;ZygoteState.startViaZygote

8、ZygoteState.startViaZygote

startViaZygote函数,主要是将传递进来的参数拼接成成字符串和收集起来。其中processClass是

  1. private Process.ProcessStartResult startViaZygote(...)
  2. throws ZygoteStartFailedEx {
  3. //根据传递进来的参数,拼接成字符串并收集到ArrayList&lt;String&gt;类型argsForZygote
  4. //将作为新应用程序的主函数的参数
  5. return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
  6. zygotePolicyFlags,
  7. argsForZygote);
  8. }

9、ZygoteState.openZygoteSocketIfNeeded

zygoteSendArgsAndGetResult的第一个参数,调用了openZygoteSocketIfNeeded函数。尝试建立与Socket的连接(如果之前未建立的话)。我们知道Zygote进程在创建的过程,会调用runSelectLoop函数,创建Server端的Socket,一直等待来自AMS的Client端的Socket创建进程请求。

  1. private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
  2. try {
  3. //建立和Zygote的Socket连接
  4. attemptConnectionToPrimaryZygote();
  5. //匹配abi的架构。在Zygote的创建对应四种模式:32,32_64和64,64_32
  6. //32,64
  7. if (primaryZygoteState.matches(abi)) {
  8. return primaryZygoteState;
  9. }
  10. //主要架构模式不配,匹配第二种 32_64,64_32
  11. if (mZygoteSecondarySocketAddress != null) {
  12. // The primary zygote didn't match. Try the secondary.
  13. attemptConnectionToSecondaryZygote();
  14. if (secondaryZygoteState.matches(abi)) {
  15. return secondaryZygoteState;
  16. }
  17. }
  18. } catch (IOException ioe) {
  19. throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
  20. }
  21. throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
  22. }

attemptConnectionToPrimaryZygote函数主要通过底层的LocalSocket创建与Zygote进程的Socket连接,并获得输入流zygoteInputStream和输出流zygoteOutputWriter。

  1. private void attemptConnectionToPrimaryZygote() throws IOException {
  2. if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
  3. primaryZygoteState =
  4. ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
  5. maybeSetApiBlacklistExemptions(primaryZygoteState, false);
  6. maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
  7. }
  8. }

和Zygote进程的Server端Socket建立连接后,就是开始往Socket写数据了。

10、attemptZygoteSendArgsAndGetResult

回到第8步调用了zygoteSendArgsAndGetResult函数,又调用了attemptZygoteSendArgsAndGetResult函数。

  1. zygoteSendArgsAndGetResult=&gt;attemptZygoteSendArgsAndGetResult

11、attemptZygoteSendArgsAndGetResult

到这里,通过Socket的方式向Zygote进程写进前面拼接好的参数,Zygote在Server端的Socket接收到数据之后,会执行创建动作。在返回的result.pid>=0表示创建成功,并运行在新的进程。

  1. private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
  2. ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
  3. try {
  4. final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
  5. final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
  6. zygoteWriter.write(msgStr);
  7. zygoteWriter.flush();
  8. Process.ProcessStartResult result = new Process.ProcessStartResult();
  9. result.pid = zygoteInputStream.readInt();
  10. result.usingWrapper = zygoteInputStream.readBoolean();
  11. if (result.pid &lt; 0) {
  12. throw new ZygoteStartFailedEx("fork() failed");
  13. }
  14. return result;
  15. } catch (IOException ex) {
  16. zygoteState.close();
  17. Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
  18. + ex.toString());
  19. throw new ZygoteStartFailedEx(ex);
  20. }
  21. }

12、Zygote.main

在Zygote的启动流程过程,调用了ZygoteInit的main函数,因为Zygote是通过fork自身来创建其他进程,所以需要根据传递进来的参数,进行判断是启动什么类型的进程,例如自身isPrimaryZygote=true,或者SystemServer进程。然后通过ZygoteServer.runSelectLoop函数,等待其他进程请求创建新的进程。

  1. public static void main(String argv[]) {
  2. ZygoteServer zygoteServer = null;
  3. Runnable caller;
  4. try {
  5. ...
  6. boolean startSystemServer = false;
  7. String zygoteSocketName = "zygote";
  8. String abiList = null;
  9. boolean enableLazyPreload = false;
  10. for (int i = 1; i &lt; argv.length; i++) {
  11. if ("start-system-server".equals(argv[i])) {
  12. startSystemServer = true; //判断是否SystemServer进程
  13. } else if ("--enable-lazy-preload".equals(argv[i])) {
  14. enableLazyPreload = true;
  15. } else if (argv[i].startsWith(ABI_LIST_ARG)) {
  16. abiList = argv[i].substring(ABI_LIST_ARG.length());
  17. } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
  18. //SCOKET_NAME_ARG="--socket-name=",根据参数得到SocketName
  19. zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
  20. } else {
  21. throw new RuntimeException("Unknown command line argument: " + argv[i]);
  22. }
  23. }
  24. //PRIMARY_SOCKET_NAME=zygote
  25. final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
  26. gcAndFinalize();
  27. Zygote.initNativeState(isPrimaryZygote);
  28. ZygoteHooks.stopZygoteNoThreadCreation();
  29. zygoteServer = new ZygoteServer(isPrimaryZygote);
  30. if (startSystemServer) {
  31. //启动SystemServer进程
  32. Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
  33. if (r != null) {
  34. r.run();
  35. return;
  36. }
  37. }
  38. //循环等待AMS来请求创建新的进程
  39. caller = zygoteServer.runSelectLoop(abiList);
  40. } catch (Throwable ex) {
  41. Log.e(TAG, "System zygote died with exception", ex);
  42. throw ex;
  43. } finally {
  44. if (zygoteServer != null) {
  45. zygoteServer.closeServerSocket();
  46. }
  47. }
  48. //调用新的进程主函数
  49. if (caller != null) {
  50. caller.run();
  51. }
  52. }

13、ZygoteServer.runSelectLoo

这里只关注ZygoteServer.runSelectLoop函数,接受Socket客户端数据。

  1. /**
  2. * Runs the zygote process's select loop. Accepts new connections as
  3. * they happen, and reads commands from connections one spawn-request's
  4. * worth at a time.
  5. */
  6. Runnable runSelectLoop(String abiList) {
  7. while (true) {
  8. ...
  9. ZygoteConnection connection = peers.get(pollIndex);
  10. final Runnable command = connection.processOneCommand(this);
  11. ...
  12. if (mIsForkChild) {
  13. return command;
  14. }
  15. ....
  16. }
  17. }

14、ZygoteConnection.processOneCommand

runSelctLoop主要是从循环中检测是否有连接建立,建立之后执行ZygoteConnection的processOneCommand函数,并返回一个Runable类型的command对象。

  1. Runnable processOneCommand(ZygoteServer zygoteServer) {
  2. ...
  3. args = Zygote.readArgumentList(mSocketReader);
  4. //根据参数内容,作其他类型的处理
  5. ...
  6. //创建进程,调用底层nativeForkAndSpecialize方法,通过fork当前进程来创建一个子线程。
  7. pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
  8. parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
  9. parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
  10. parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
  11. parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
  12. parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
  13. ...
  14. if (pid == 0) {
  15. //设置mIsForkChild=true
  16. zygoteServer.setForkChild();
  17. //关闭Socket连接
  18. zygoteServer.closeServerSocket();
  19. IoUtils.closeQuietly(serverPipeFd);
  20. serverPipeFd = null;
  21. //执行子进程内容
  22. return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
  23. }
  24. ...
  25. }

15、handleChildProc

handleChildProc函数。

  1. private Runnable handleChildProc(ZygoteArguments parsedArgs,
  2. FileDescriptor pipeFd, boolean isZygote) {
  3. ...
  4. if (!isZygote) {
  5. return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
  6. parsedArgs.mDisabledCompatChanges,
  7. parsedArgs.mRemainingArgs, null /* classLoader */);
  8. } else {
  9. return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
  10. parsedArgs.mRemainingArgs, null /* classLoader */);
  11. }
  12. }

16、 ZygoteInit.zygoteInit

  1. public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
  2. String[] argv, ClassLoader classLoader) {
  3. RuntimeInit.commonInit();
  4. ZygoteInit.nativeZygoteInit();//为新进程创建Binder线程池
  5. return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
  6. classLoader);
  7. }

以前还以为每个进程共用一个Binder线程池,现在知道每个进程都有自己的Binder线程池进行IPC。

17、RuntimeInit.applicationInit

  1. protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
  2. String[] argv, ClassLoader classLoader) {
  3. final Arguments args = new Arguments(argv);
  4. return findStaticMain(args.startClass, args.startArgs, classLoader);
  5. }

这里的args.startClass就是Socket客户端传递下来的android.app.ActivityThread。

18、RuntimeInit.findStaticMain

RuntimeInit.findStaticMain函数主要通过反射创建ActivityThread类的实例,并反射主函数main,然后封装到MethodAndArgsCaller实例中返回。

  1. protected static Runnable findStaticMain(String className, String[] argv,
  2. ClassLoader classLoader) {
  3. ...
  4. Class&lt;?&gt; cl = Class.forName(className, true, classLoader);
  5. Method m = cl.getMethod("main", new Class[] { String[].class });
  6. ...
  7. return new MethodAndArgsCaller(m, argv);
  8. }

MethodAndArgsCaller类继承自Runable,并在其run函数,调用主函数方法。

  1. static class MethodAndArgsCaller implements Runnable {
  2. /** method to call */
  3. private final Method mMethod;
  4. /** argument array */
  5. private final String[] mArgs;
  6. public MethodAndArgsCaller(Method method, String[] args) {
  7. mMethod = method;
  8. mArgs = args;
  9. }
  10. public void run() {
  11. ...
  12. mMethod.invoke(null, new Object[] { mArgs });
  13. ...
  14. }
  15. }

随着findStaticMain函数方法栈一路返回到runSelectLoop函数,因为mIsForkChild是true,所以MethodAndArgsCaller对象返回到ZygoteInit的main函数,并赋值给caller变量。main函数最后调用caller的run函数。即执行了ActivityThread的主函数main。

本来自己还有个疑惑,fork子进程之后,并caller的run函数,已经退出了Zygote进程的runSelectLoop循环等待。怎么继续去接收AMS新的请求。原来如此,fork子进程后,后续的代码都运行在了子进程,这里return其实是子进程了。

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

19、进程ActivityThread.main。

  1. public static void main(String[] args) {
  2. Looper.prepareMainLooper();
  3. ActivityThread thread = new ActivityThread();
  4. thread.attach(false, startSeq);
  5. if (sMainThreadHandler == null) {
  6. sMainThreadHandler = thread.getHandler();
  7. }
  8. Looper.loop();
  9. }

ActivityThread的主函数,创建了ActivityThread进程,并启动了消息循环队列,代表着当前进程的主线程已启动。

知识点

  • fork函数。
  • 通过Socket创建新的进程。
  • Binder机制和应用程序创建的时机。
  • ActivityThread的进程的主线程。

疑问点

  • 通过Zygote进程fork而来的子进程都会获得Zygote创建的Java虚拟机,也就是每个应用进程都有自己的Java虚拟机。
  • 每个应用进程都有属于自己的Binder线程池和消息循环机制。
  • 之所以fork Zygote进程而不是init进程,是避免重复初始化环境资源的加载和虚拟机的创建。
  • 进程的创建之所选择Socket机制进行,因为Binder机制会导致死锁,怕父进程binder线程有锁,然后子进程的主线程一直在等其子线程(从父进程拷贝过来的子进程)的资源,但是其实父进程的子进程并没有被拷贝过来,造成死锁,所以fork不允许存在多线程

以上就是Android 应用程序的启动流程示例详解的详细内容,更多关于Android 程序启动流程的资料请关注w3xue其它相关文章!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号