- 概述
- 1. Process.start
- 2. startViaZygote
- 3. zygoteSendArgsAndGetResult
- 4. runSelectLoop
- 5. runOnce
- 6. forkAndSpecialize
- 7. handleChildProc
- 8. zygoteInit
- 9. commonInit
- 10. nativeZygoteInit
- 11. applicationInit
- 12. invokeStaticMain
- 13. MethodAndArgsCaller
- 总结
基于Android 6.0的源码剖析, 分析Android进程是如何一步步创建的,本文涉及到的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/frameworks/base/core/java/android/os/Process.java /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java /frameworks/base/core/java/com/android/internal/os/Zygote.java /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp /frameworks/base/cmds/app_process/App_main.cpp (内含AppRuntime类) /frameworks/base/core/jni/AndroidRuntime.cpp /libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java /art/runtime/native/dalvik_system_ZygoteHooks.cc /art/runtime/Runtime.cc /art/runtime/Thread.cc /art/runtime/signal_catcher.cc |
概述
本文要介绍的是进程的创建,先简单说说进程与线程的区别。
进程:每个App
在启动前必须先创建一个进程,该进程是由Zygote
fork出来的,进程具有独立的资源空间,用于承载App上运行的各种Activity/Service等组件。进程对于上层应用来说是完全透明的,这也是google有意为之,让App程序都是运行在Android Runtime。大多数情况一个App
就运行在一个进程中,除非在AndroidManifest.xml中配置Android:process
属性,或通过native代码fork进程。
线程:线程对应用开发者来说非常熟悉,比如每次new Thread().start()
都会创建一个新的线程,该线程并没有自己独立的地址空间,而是与其所在进程之间资源共享。从Linux角度来说进程与线程都是一个task_struct结构体,除了是否共享资源外,并没有其他本质的区别。
对于大多数的应用开发者来说创建线程比较熟悉,而对于创建进程并没有太多的概念。对于系统工程师或者高级开发者,还是有很必要了解Android系统是如何一步步地创建出一个进程的。先来看一张进程创建过程的简要图:
图解:
- App发起进程:当从桌面启动应用,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送消息给system_server进程;
- system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;
- zygote进程:在执行
ZygoteInit.main()
后便进入runSelectLoop()
循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程; - 新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。
可能朋友不是很了解system_server进程和Zygote进程,下面简要说说:
system_server
进程:是用于管理整个Java framework层,包含ActivityManager,PowerManager等各种系统服务;Zygote
进程:是Android系统的首个Java进程,Zygote是所有Java进程的父进程,包括system_server
进程以及所有的App进程都是Zygote的子进程,注意这里说的是子进程,而非子线程。
如果想更进一步了解system_server进程和Zygote进程在整个Android系统所处的地位,可查看我的另一个文章Android系统-开篇。
接下来从Android 6.0源码,展开讲解进程创建是一个怎样的过程。
1. Process.start
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String[] zygoteArgs) { try { //【见流程2】 return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, zygoteArgs); } catch (ZygoteStartFailedEx ex) { throw new RuntimeException(""); } } |
2. startViaZygote
[-> Process.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
private static ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { ArrayList argsForZygote = new ArrayList(); argsForZygote.add("--runtime-args"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); argsForZygote.add("--target-sdk-version=" + targetSdkVersion); if (niceName != null) { argsForZygote.add("--nice-name=" + niceName); } if (appDataDir != null) { argsForZygote.add("--app-data-dir=" + appDataDir); } argsForZygote.add(processClass); if (extraArgs != null) { for (String arg : extraArgs) { argsForZygote.add(arg); } } //【见流程3】 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } } |
该过程主要工作是生成argsForZygote
数组,该数组保存了进程的uid、gid、groups、target-sdk、nice-name等一系列的参数。
3. zygoteSendArgsAndGetResult
[-> Process.java]
Step 3-1. openZygoteSocketIfNeeded
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } //当主zygote没能匹配成功,则尝试第二个zygote if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); } } if (secondaryZygoteState.matches(abi)) { return secondaryZygoteState; } throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi); } |
openZygoteSocketIfNeeded(abi)
方法是根据当前的abi来选择与zygote还是zygote64来进行通信。
Step 3-2. zygoteSendArgsAndGetResult
|