Zygote 又init.rc脚本解析启动。以下只考虑 Zygote 的启动而不考虑 init.rc 的解析。已知Zygote 的入口函数是app_main.cpp的main()函数。
一下是涉及到的文件路径
app_main.cpp(.../frameworks/base/cmds/app_process/app_main.cpp)
AndroidRuntime.cpp(.../frameworks/base/core/jni/AndroidRuntime.cpp)
RuntimeInit.java(.../frameworks/base/core/java/com/android/internal/os/RuntimeInit.java)
Zygote.java(../frameworks/base/core/java/com/android/internal/os/Zygote.java)
ZygoteInit.java(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
ZygoteConnection.java(.../frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java)
com_android.internal_os_Zygote.cpp(.../frameworks/base/core/jni/com_android_internal_os_Zygote.cpp)
ZygoteHooks.java(.../libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java);
.../frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]){
...
//Android运行时环境
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
boolean zygote = false;
boolean startSystemServer = false;
boolean application = false;
String8 niceName;
String8 className;
...
//根据入参,决定当前程序的行为
while(i < argc) {
const char* arg = argv[i++];
if(strcmp(arg, "--zygote") == 0){ //当前进程是否承载 zygote
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if(strcmp(arg, "--start-system-server") == 0){ // 是否需要启动system server
startSystemServer = true;
} else if(strcmp(arg, "--application") == 0){ //是否进入独立的程序
application = true;
} else if(strncmp(arg, "--nice-name=",12) ==0){//程序别名
niceName.setTo(arg + 12);
} else if(strncmp(arg, "--",2)!=0) {
className.setTo(arg);
}else{
i--;
break;
}
}
...
if(!className.isEmpty()){
...
}else{
//将启动 system server 入参
if(startSystemServer){
args.add(String8("start--system-server"));
}
}
...
if(zygote){
//表示要启动 Zygote
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}else if(className)){
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
}
//以 zygote = true 为例,这里的 className 为"com.android.internal.os.ZygoteInit"
//.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
void AndroidRuntime::start(const char* className, const Vertor& options, bool zygote){
...
if(startVm(&mJavaVm, &env, zygote) != 0 ){//启动虚拟机
return;
}
onVmCreate(env);//虚拟机启动后的回调
...
//由 JNI 启动对应的类的入口函数
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if(startClass == NULL){
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
}else{
//入口函数设定为 void static main(String[] args),由 jni 进行调用
//此时执行ZygoteInit.main()函数
jmethodId startMeth = env->GetStaticMethodID(startClass,"main",
"([Ljava/lang/String;])V");
if(startMeth == NULL){
ALOGE("JavaVM unable to find main() in '%s'\n", className);
}else{
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
}
由上面通过 JNI 调用,转到 ZygoteInit.main()函数,同理zygote=false 的时候执行com.android.internal.os.RuntimeInit.main()
(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
public static void main(String argv[]){
...
boolean startSytemServer = false;
String sockName = "zygote";
...
for( int i = 1; i < argv.length; i++){
if("start-system-server".equals(argv[i])){
startSystemServer = true;//表示需要启动 system server
} ...
...
}
...
//注册一个 socket,AMS 通知 Zygote fork 是通过 socket 通信的
registerZygoteSocket(socketName);
...
preload();//预加载各类资源
...
//第一部分,startSystemServer 为 true,进行 system server的孵化
if(startSystemServer){
//启动 system server
startSystemServer(abList, socketName);
}
//第二部分,开启 loop,进行 socket 监听,孵化普通进程
runSelectLoop(abList);
closeServerSocket();
}
registerZygoteSocket(socketName)我就先不看了 暂时也不了解 Linux 的socket 通信
//从各个子函数就能得到其作用了
//(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
static void preload(){
preloadClasses();
preloadResources();
preloadOpenGL();
preloadSharedLibraries();
preloadTextResources();
WebViewFactory.prepareWebViewInZygote();
}
这里开始第一部分的研究,就是system server 的孵化。主要关注下startSystemServer(abList,socketName)
(.../frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
private static boolean startSystemServer(String abList,String socketName){
...
String args[] = {
"--setuid=1000",
"--setgid=1000",
"---setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,2032,3001,3002,3003,3006,3007",
"--capabilities="+capabilities+","+capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
...
//将 args 对应解析
parsedArgs = new ZygoteConnection.Arguments(args);
//主流程1,fork 进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
if(pid ==0){
...
//流程2,初始化 system server 进程
handleSystemServerProcess(parsedArgs);
}
}
先分析流程1:
转到 Zygote.java
//.../frameworks/base/core/java/com/android/internal/os/Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[ ][ ] rlimits, long permittedCapabilities, long effectiveCapabilities){
...
int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
...
}
native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
兜兜转转走到了 native 方法去了,具体的方法名为com_android_internal_os_Zygote_nativeForkSystemServer
// .../frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities){
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
...
}
//注意,从 forkSystemServer 调用的参数is_system_server = true
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
pid_t pid = fork();
...
//关键代码
//从下面的register_com_android_internal_os_Zygote()可以得到
//gZygoteClass 是"com.android.internal.os.Zygote"
//gClassPostForkChildHooks 是callPostForkChildHooks(int String)函数
env->CallStaticVoidMethod(gZygoteClass, gClassPostForkChildHooks, debug_flags, is_system_server ? NULL : instructionSet);
...
}
static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
int register_com_android_internal_os_Zygote(JNIEnv* env) {
gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
"(ILjava/lang/String;)V");
return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
}
当 linux fork 好进程后,又通过 JNI 跳转到 Zygote.java,callPostForkChildHooks主要进行孵化后的一些处理工作,不是这里的重点,略过
private static final ZygoteHooks VM_HOOKS = new ZygoteHooks();
private static void callPostForkChildHooks(int debugFlags, String instructionSet){
//这里的instructionSet 是 null
VM_HOOKS.postForkChild(debugFlags, instructionSet);
}
到此流程1分析结束,后分析流程2(handleSystemServerProcess()@ZygoteInit.java)
private static void handleSystemServerProcess(ZygoteConnection.Arguments parseArgs){
...
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
进入到 RuntimeInit.java
.../frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader){
...
commonInit();//①
nativeZygoteInit();//②
applicationInit(targetSdbVersion, argv, classLoader);//③
}
①通用部分初始化,包括设置默认的uncaught exception handler(具体是RuntimeInit 中的UncaughtHandler 类);为HttpURLConnection准备好默认的 HTTP User-Agent(User Agent 包含了与系统浏览器相关的一系列信息)[我看的是6.0代码,据说6.0已经采用 OkHttp 了,关于 HttpURLConnection 的初始化待定]
②负责本地初始化重点研究,native 实现在 com_android_internal_os_RuntimeInit_nativeZygoteInit@AndroidRuntime.cpp,主要是回调起onZygoteInit@app_main.cpp,调用 startThredPool 开启 Binder 线程池以保证其他进程可以正确访问到 Zygote 所提供的服务。
③程序起点
先来分析③
.../frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){
...
//这里的startClass就是前面的"com.android.server.SystemServer"
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader){
//com.android.server.SystemServer
Class> cl = Class.forName(className, true, classLoader);
Method m = cl.getMethod("main", new Class[]{String[].class});
...
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
ZygoteInit.MethodAndArgsCaller 是一个 Exception,在最早调用的 ZygoteInit.java的 main()函数中捕获
try{
...
if(startSystemServer){
startSystemServer(abiList, socketName);
}
...
}catch(MethodAndArgsCaller caller){
caller.run();
}
可以得知,这里是通过捕获异常的方式,调用了run()@ZygoteInit.MethodAndArgsCaller
public void run()@ZygoteInit.MethodAndArgsCaller{
mMethod.invoke(null, new Object[]{mArgs});
}
由 run()方法进入到 SystemServer.main(String[] args)方法。
到此,第一部分 SystemServer 的启动结束。
第二部分
public static void main(String argv[])@ZygoteInit{
...
runSelectLoop(abiList);
....
}
private static void runSelectLoop(String abiList){
...
ArrayList peers = new ArrayList();
...
while(true){
if(i == 0){
...
}else {
boolean done = peer.get(i).runOnce();
...
}
}
}
boolean runOnce()@ZygoteConnection{
...
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
...
if(pid ==0 ){
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
}else{
//主要进行扫尾工作,将子进程加入进程组,正确关闭文件等
handleParentProc(pid, descriptor, serverPipeFd, parsedArgs);
}
...
}
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
String instructionSet, String appDataDir) {
//主要进行堆空间的初始化
VM_HOOKS.preFork();
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
instructionSet, appDataDir);
if (pid == 0) {
...
}
VM_HOOKS.postForkCommon();
return pid;
}
//该方法定义在.../frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
String instructionSet, String appDataDir);
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint debug_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
se_name, false, fdsToClose, instructionSet, appDataDir);
}
//注意 这里 fork 的是普通进程,调用的参数is_system_server = true
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint debug_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
pid_t pid = fork();
...
//关键代码
//从下面的register_com_android_internal_os_Zygote()可以得到
//gZygoteClass 是"com.android.internal.os.Zygote"
//gClassPostForkChildHooks 是callPostForkChildHooks(int String)函数
env->CallStaticVoidMethod(gZygoteClass, gClassPostForkChildHooks, debug_flags, is_system_server ? NULL : instructionSet);
...
这里的主要作用是 fork 一个进程,主要的初始化还是handleChildProc()@ZygoteConnection.java
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr){
...
if(...){
}else{
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null);
}
}
和 system server 的流程大致一样
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){
...
commonInit();
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
不同的是,在 system server 的执行流程中,applicationInit 中调用的是SystemServer.main(),那么在普通的 applicationInit()执行的又是哪个类的main()呢,主要还是要要找args.startClass这个变量。往上推,可以得到 args 在runOnce()@ZygoteConnection 中初始化,
boolean runOnce(){
...
String args[];
Arguments parsedArgs = null;
...
args = readArgumentList();
...
parsedArgs = new Arguments();
}
所以参数的关键在readArgumentList()中
private String[ ] readArgumentList(){
...
String[] result = new String[argc];
for(int i = 0, i < argc, i++){
result[i] = mSocketReader.readLine();
}
return result;
}
所以这个启动的参数是由 socket 通信带过来的,一般来说是由 ActivityManagerService 利用 socket 通知 zygote 孵化一个新的进程,参数自然就由 ActivityManagerService带过来
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){
...
if(entryPoint == null) entryPoint = "android.app.ActivityThread";
...
Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdlVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs);
...
}
普遍情况下,即 entryPoint = null 的时候,告诉 zygote 在孵化完成进程后,在子进程执行 android.app.ActivityThread.main(String[]) 方法。
于是流程二分析完毕。
由 system server 和普通情况下的进程孵化可以得知,zygote 对于进程孵化的流程大同小异,只是在孵化好子进程后,在子进程执行的是 SystemServer.main(String[])还是 ActivityThread.main(String[])
总结下调用的流程:
- main@app_main.cpp
- start("com.android.internal.os.ZygoteInit",args,zygote = true)@AndroidRuntime.cpp
- [email protected]
- [email protected]//启动虚拟机
- [email protected]//虚拟机启动后的回调
- JNI 调用CallStartVoidMethod(),执行 [email protected]
- [email protected]
- [email protected]//注册一个 socket,用来通信孵化进程
- [email protected]//预加载各种资源
- if(startSystemServer) [email protected]//流程一
- [email protected]//流程二
流程一:
- [email protected]//孵化 system server 进程
- Zygote.forkSystemServer//参数指定com.android.server.SystemServer
- forkSystemServer@Zygote
- nativeForkSystemServer@Zygote
- com_android_internal_os_Zygote_nativeForkSystemServer@com_android_internal_os_Zygote.cpp
- ForkAndSpecializeCommon(...,isSystemServer = true,...)@com_android_internal_os_Zygote.cpp
- ForkAndSpecializeCommon(...,isSystemServer = true,...)@com_android_internal_os_Zygote.cpp
- JNI调用 CallStaticVoidMethod,执行CallPostForkChildHooks@Zygot进程孵化后的一些处理工作
- 在孵化后的子进程[email protected]
- RuntimeInit.ZygoteInit()
- ZygoteInit@RuntimeInit
- commonInte@RuntimeInit//通用部分初始化
- nativeZygoteInit@RuntimeInit//关键是开启 Binder 线程池让其他进程可以访问 Zygote 提供的服务
- applicationInit@RuntimeInit
- application@RuntimeInit
- invokeStaticMain@RuntimeInit
- invokeStaticMain@RuntimeInit
- throw ZygoteInit.MethodAndArgsCaller//参数是 SystemServer.main(String[]),这里是抛出一个异常,在 main@ZygoteInit 捕获
- main@ZygoteInit
- caller.run
- [email protected]
- java 层的反射调用method.invoke,执行 SystemServer.main 函数
- 至此,孵化好system_server 进程后,在其子进程执行 SystemServer.main()函数
流程二:
- [email protected] //loop,监听 socket 孵化进程
- runOnce@ZygoteConnection
- runOnce@ZygoteConnection
- args = readArgumentList()//获取 socket 传来的参数,一般是AMS 需要孵化新进程的请求,携带参数android.app.ActivityThread
- Zygote.forkAndSpecialize
- forkAndSpecialize@Zygote
- nativeForkAndSpecialize@Zygote
- com_android_internal_os_Zygote_nativeForkAndSpecialize@com_android_internal_os_Zygote.cpp
- ForkAndSpecializeCommon(...,is_system_server = false,...)@com_android_internal_os_Zygote.cpp
- JNI 调用 CallStaticVoidMethod,执行CallPostForkChildHooks@Zygot进程孵化后的一些处理工作
- 在孵化后的子进程 handleChildProc@ZygoteConnection
- RuntimeInit.zygoteInit(),关键参数是 android.app.ActivityThread
- commonInit@RuntimeInit
- nativeZygoteInit@RuntimeInit
- applicationInit@RuntimeInit
- RuntimeInit.zygoteInit(),关键参数是 android.app.ActivityThread
- application@RuntimeInit
- invokeStaticMethod@RuntimeInit
- throw new ZygoteInit.MethodAndArgsCaller(m, argv)抛出异常在main@ZygoteInit 捕获
- main@ZygoteInit
- caller.run()
- [email protected]
- 反射调用mMethod.invoke在孵化后的子进程执行Activity.main()
于是就进行了 SystmServer 进程的初始化(入口在 SystemServer.main(String[ ])),同时 socket 监听,一旦有来自 AMS 的进程孵化请求,则孵化子进程,并且在子进程执行 ActivityThread.main(String[ ])进行子进程的初始化
自己画的流程图 略丑