Anroid 系统服务进程与应用程序进程启动过程对比

同样是 fork 自 zygote 进程,系统服务进程与应用进程有什么区别呢?先说回 zygote 进程做的事情,在 ZygoteInit 类中调用 main 方法,

public static void main(String argv[]) {
    //省略...
    final Runnable caller;
    //省略...
    //1.注册 socket
    zygoteServer.registerServerSocketFromEnv(socketName);
    //2.启动系统服务进程
    if(startSystemServer) {
        Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
        if(r != null) {
            r.run();
            return;
        }
    }
    //3.监听启动进程请求
    caller = zygoteServer.runSelectLoop(abiList);
    //在子进程中执行
    if (caller != null) {
        caller.run();
    }
}

main 方法里主要做了 3 件事情,1.注册 socket 端口,2.启动系统服务进程,3.监听 fork 进程请求。注册 socket 先不管,监听 fork 进程请求,之前也整理过了,阅读笔记见 Android 进阶解密读书笔记2 。整理完 Android 进阶解密读书笔记2 之后,发现系统服务进程的启动和应用程序进程的启动有很多相似点,所以在此对比整理。

根据上面代码,先来看看 forkSystemServer 方法,

private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
    //省略...
    //这里设置一些参数,留意最后一个参数值,这个就等同于启动应用进程的入口点 ActivityThread
    String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
        };
    //省略...
    //这步是 fork 系统服务进程,创建应用进程用的是 Zygote.forkAndSpecialize 方法
    pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
    //省略...
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        //这步说是系统服务进程不需要 socket,于是就把 zygote 进程 fork 来的 socket 关闭
        zygoteServer.closeServerSocket();
        //继续处理启动系统服务进程
        return handleSystemServerProcess(parsedArgs);
    }
    //省略...
}

再进一步看看 handleSystemServerProcess 方法,

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs){
    //省略...
    //这步就和创建应用进程时调的方法是一样了,包括后面的创建 Binder 线程池,反射调用 main 方法。
    return ZygoteInit.zygoteInit(parseArgs.targetSdkVersion, parseArgs.remainingArgs, cl);
}

最后,系统服务进程启动后会调用 com.android.server.SystemServer 的 main 方法,这个类就是前面设置参数时指定的。

总结

通过上述分析对比,启动系统服务进程和启动应用程序进程的相同点:

  • 在 zygote 进程上,起点都在 main 方法中。
  • 都需要做一些参数设置准备。
  • 最后都调用了 ZygoteInit 的 zygoteInit 静态方法。在方法内部都去创建了 Binder 线程池,调用入口类的 main 方法。

启动系统服务进程和启动应用程序进程的不同点:

  • 系统服务进程在 zygote 进程启动时就会启动,应用进程则需要看情况,zygote 进程监听处理。
  • 系统服务进程创建时调用了 Zygote.forkSystemServer 方法,应用进程创建时则调用 Zygote.forkAndSpecialize 这个通用方法。
  • 系统服务进程的入口类是 SystemServer,应用进程的入口类是 ActivityThread。以及他们各自 *main *方法的工作内容也是不同的。

你可能感兴趣的:(Anroid 系统服务进程与应用程序进程启动过程对比)