【Binder 源码】APP 进程的创建

作者: 程序老秃子 | 来源:发表于2022-11-11 17:18 被阅读0次

创建进程

现在以一个APP的进程为Client进程,然后我们创建的一个AIDL服务为Server进程,我们主要分析下这两者直接是怎么通信。

因为APP的进程为Client进程,所以Client进程的创建,那也就是APP进程的创建。我们主要分析下一个APP的进程是怎么创建出来的,会不会也和ServiceManager进程那样有内存映射呢?

Android系统启动第一个进程为init进程,init进程通过解析init.rc来fork出zygote进程。Android的其他进程都是有Zygote进程fork出来的。所以APP进程也是有Zygote进程fork出来的。

1.zygote进程创建

当zygote创建出来之后,会加载到 /frameworks/base/cmds/app_process/app_main.cpp的main()方法

int main(int argc, char* const argv[])
{
//.....
     if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
     } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
     } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
     }
//.....
}

该main()里面的功能:通过Android虚拟机AppRuntime来启动不同的类的main()方法。通过执行ZygoteInit的main(),完成Zygote进程的职责

2.zygote进程功能加载

在Zygote进程启动之后,执行ZygoteInit的main()来实现zygote进程功能加载,主要逻辑如下:

  • (1)创建一个Server端的ZygoteServer,等待ActivityManagerService请求来创建APP进程
  • (2)通过forkSystemServer()来fork出SystemServer进程

ZygoteInit的main()里面对应的代码位于 /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,简单的贴一点主要逻辑代码如下:

 public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;
        //.....
        Runnable caller;
        try {
             //.....
           for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                }
                 //..... 
                 else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                }
             //.....
        }
            //与AMS socket通信的server
            zygoteServer = new ZygoteServer(isPrimaryZygote);
            //SystemServer进程的创建
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
                // child (system_server) process.
                if (r != null) {
                    r.run();
                    return;
                }
            }
            //循环等待AMS发出fork进程的通知
            caller = zygoteServer.runSelectLoop(abiList);
        } finally {
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }
        //启动子进程
        if (caller != null) {
            caller.run();
        }
    }

简单的将里面的点总结下:

(1)ZygoteServer职责

在Zygote进程第一次启动的时候创建ZygoteServer,作用就是与AMS建立Socket通信的服务端。AMS发出创建APP进程的通知时,就会通过socket通信通知Zygote进程创建APP进程。

主要通过 zygoteServer.runSelectLoop(abiList)启动一个循环,等待AMS来发送请求。对应的代码位于frameworks/base/core/java/com/android/internal/os/ZygoteServer.java,简单的贴一点主要逻辑代码如下:

 Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
 
        fds.add(mServerSocket.getFileDescriptor());
        peers.add(null);
 
        while (true) {
     //.......
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
 
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    try {
                        //当接收到需要创建APP进程的消息,通过processOneCommand来创建进程
                        ZygoteConnection connection = peers.get(i);
                        final Runnable command = connection.processOneCommand(this);
                        // 当前是子进程
                        if (mIsForkChild) {
                            // We're in the child. We should always have a command to run at this
                            // stage if processOneCommand hasn't called "exec".
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }
 
                            return command;
                        } else {
                          //如果在server进程中,不应该有任何需要运行的命令
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            }
 
                             //.......
                        }
                    }
                    //.......
                }
            }
        }
    }

这样接收到AMS发过来的请求的时候,最终会通过jni调用到Native的 app_main.cpp下的onZygoteInit()方法来创建APP进程。

小结:

  • 1.ZygoteServer作用:在zygote进程中创建socket的server端,通过socket通信接收AMS的创建进程的请求;
  • 2.在ZygoteServer中维护着一个死循环,接收AMS发出请求;

(2)system_server进程

在Android系统启动加载Zygote进程的时候,通过ZygoteInit#forkSystemServer()中来调用到Zygote.forkSystemServer()来创建出system_server进程。因为这个章节的内容比较多,所以单独拉出见 “二 system_server进程 ”。

小结:

  • 1.通过zygote进程fork出system_server进程;
  • 2.最终调用到Native的app_main.cpp下的onZygoteInit()来对system_server进程进行初始化;
  • 3.通过RuntimeInit.applicationInit来加载system_server进程的功能;
  • 4.system_server进程的功能实现类对应的com.android.server.SystemServer。

3.小结zygote进程

(1)zygote进程是运行在Android虚拟机上,通过AppRuntime启动的zygote进程对应的功能;
(2)zygote进程有两个作用:一个是创建一个与AMS进行socket通信的server端,等待接收AMS发出创建进程的请求;另一个是fork出system_server进程;
(3)对system_server进程进行初始化之后,通过执行com.android.server.SystemServer#main(),来实现system_server进程的功能:启动一些重要的系统service

文末

本文源代码获取方式:可点击此处查看直达方式 或者 简信 发送 “底层源码” 即可 免费获取;并且还为大家特别提供下面这一套 Android Framework 高工学习手册;里面的内容真的是为深入学习 Framework 的小伙伴量身打造的!今天特地拿出来分享一下,这个是非常值得每一个 Android 开发者去学习和收藏

Framework 高工学习手册— Liunx 内存基础篇

Framework 高工学习手册— Binder 源码篇

Framework 高工学习手册—Hander消息机制篇

Framework 高工学习手册—AMS篇

Framework 高工学习手册—PMS篇

Framework 高工学习手册—WMS篇

需要完整版《 Android Framework 高工学习手册》PDF 文档的小伙伴:可在评论区下方留言,或者简信发送“高工进阶”,即可 免费获取↓↓↓

相关文章

网友评论

    本文标题:【Binder 源码】APP 进程的创建

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