android 技术梳理

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

2021-01-22  本文已影响0人  jkwen

同样是 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 方法,这个类就是前面设置参数时指定的。

总结

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

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

上一篇下一篇

猜你喜欢

热点阅读