美文网首页android 技术梳理
Anroid 系统服务进程与应用程序进程启动过程对比

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

作者: jkwen | 来源:发表于2021-01-22 13:46 被阅读0次

    同样是 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 系统服务进程与应用程序进程启动过程对比

        本文链接:https://www.haomeiwen.com/subject/gvbqzktx.html