Zygote进程启动流程

参考1
参考2

概念

(1)在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的;
(2)当ActivityManagerService启动一个应用程序的时候,就会通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的进程;
(3)系统中的两个重要服务PackageManagerService和ActivityManagerService,都是由SystemServer进程来负责启动的,而SystemServer进程本身是Zygote进程在启动的过程中fork出来的。

Zygoteinit.java

(1)设置DDMS可用,初始化启动参数。
(2)调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯。
(3)调用startSystemServer函数来启动SystemServer组件
(4)调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。

Zygote进程启动流程_第1张图片
Zygoteinit.java
ZygoteInit.registerZygoteSocket

(1)这个socket接口是通过文件描述符来创建的,
(2)这个文件描符代表的就是我们前面说的/dev/socket/zygote文件了。
(3)这个文件描述符是通过环境变量ANDROID_SOCKET_ENV得到的
(4)ZygoteInit.registerZygoteSocket函数可以直接使用这个文件描述符来创建一个Java层的LocalServerSocket对象。如果其它进程也需要打开这个/dev/socket/zygote文件来和Zygote进程进行通信,那就必须要通过文件名来连接这个LocalServerSocket了

public class ZygoteInit {  
    ......  
  
    /** 
    * Registers a server socket for zygote command connections 
    * 
    * @throws RuntimeException when open fails 
    */  
    private static void registerZygoteSocket() {  
        if (sServerSocket == null) {  
            int fileDesc;  
            try {  
                String env = System.getenv(ANDROID_SOCKET_ENV);  
                fileDesc = Integer.parseInt(env);  
            } catch (RuntimeException ex) {  
                ......  
            }  
  
            try {  
                sServerSocket = new LocalServerSocket(  
                    createFileDescriptor(fileDesc));  
            } catch (IOException ex) {  
                .......  
            }  
        }  
    }  
          
    ......  
}  
Zygoteinit.startSytemServer()

(1)Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件
(2)pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。

public class ZygoteInit {  
    ......  
  
    private static boolean startSystemServer()  
            throws MethodAndArgsCaller, RuntimeException {  
        /* Hardcoded command line to start the system server */  
        String args[] = {  
            "--setuid=1000",  
            "--setgid=1000",  
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",  
            "--capabilities=130104352,130104352",  
            "--runtime-init",  
            "--nice-name=system_server",  
            "com.android.server.SystemServer",  
        };  
        ZygoteConnection.Arguments parsedArgs = null;  
  
        int pid;  
  
        try {  
            parsedArgs = new ZygoteConnection.Arguments(args);  
  
            ......  
  
            /* Request to fork the system server process */  
            pid = Zygote.forkSystemServer(  
                parsedArgs.uid, parsedArgs.gid,  
                parsedArgs.gids, debugFlags, null,  
                parsedArgs.permittedCapabilities,  
                parsedArgs.effectiveCapabilities);  
        } catch (IllegalArgumentException ex) {  
            ......  
        }  
  
        /* For child process */  
        if (pid == 0) {  
            handleSystemServerProcess(parsedArgs);  
        }  
  
        return true;  
    }  
      
    ......  
}  
Zygote.handleSystemServerProcess

(1)Zygote进程创建的子进程会继承Zygote进程在前面创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket函数来关闭它。
(2)接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作

public class ZygoteInit {  
    ......  
  
    private static void handleSystemServerProcess(  
            ZygoteConnection.Arguments parsedArgs)  
            throws ZygoteInit.MethodAndArgsCaller {  
        closeServerSocket();  
  
        /* 
        * Pass the remaining arguments to SystemServer. 
        * "--nice-name=system_server com.android.server.SystemServer" 
        */  
        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);  
        /* should never reach here */  
    }  
  
    ......  
}     
RuntimeInit.zygoteInit()

(1)一个是调用zygoteInitNative函数来执行一个Binder进程间通信机制的初始化工作
(2)调用上面传进来的com.android.server.SystemServer类的main函数。

public class RuntimeInit {    
    ......    
  
    public static final void zygoteInit(String[] argv)    
            throws ZygoteInit.MethodAndArgsCaller {    
        ......    
    
        zygoteInitNative();    
  
        ......    
  
  
        // Remaining arguments are passed to the start class's static main    
  
        String startClass = argv[curArg++];    
        String[] startArgs = new String[argv.length - curArg];    
  
        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);    
        invokeStaticMain(startClass, startArgs);    
    }    
  
    ......    
}  
ZygoteInit.runSelectLoopMode

(1)等待ActivityManagerService来连接这个Socket。
(2)然后调用ZygoteConnection.runOnce函数来创建新的应用程序

public class ZygoteInit {  
    ......  
  
    private static void runSelectLoopMode() throws MethodAndArgsCaller {  
        ArrayList fds = new ArrayList();  
        ArrayList peers = new ArrayList();  
        FileDescriptor[] fdArray = new FileDescriptor[4];  
  
        fds.add(sServerSocket.getFileDescriptor());  
        peers.add(null);  
  
        int loopCount = GC_LOOP_COUNT;  
        while (true) {  
            int index;  
  
            ......  
  
  
            try {  
                fdArray = fds.toArray(fdArray);  
                index = selectReadable(fdArray);  
            } catch (IOException ex) {  
                throw new RuntimeException("Error in select()", ex);  
            }  
  
            if (index < 0) {  
                throw new RuntimeException("Error in select()");  
            } else if (index == 0) {  
                ZygoteConnection newPeer = acceptCommandPeer();  
                peers.add(newPeer);  
                fds.add(newPeer.getFileDesciptor());  
            } else {  
                boolean done;  
                done = peers.get(index).runOnce();  
  
                if (done) {  
                    peers.remove(index);  
                    fds.remove(index);  
                }  
            }  
        }  
    }  
  
    ......  
}        
总结:Zygote启动流程

初始化DDMS
注册Zygote进程的Socket
加载class、resource、OpenGL、WebView等各种资源
fork出SystemServer进程
启动SystemServer进程
调用runSelectLoop()一直监听Socket信息
收到创建应用程序Socket消息,调用ZygoteConnection#runOnce()。在runOnce()中调用Zygote#forkAndSpecialize()创建应用进程
启动应用进程

  1. 系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。

  2. Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。

  3. 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。

你可能感兴趣的:(Zygote进程启动流程)