Zygote解析

一、Zygote简介

init会创建Zygote进程,SystemServer进程和应用进程都是Zygote(孵化器)fock(复制进程)出来的。所以有必要了解下Zygote的流程。

二、Zygote启动流程

分析Zygote启动首先会调用ZygoteInit的main函数。

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    ......
    try {
        ......
        //创建Server Socket
        zygoteServer.registerServerSocketFromEnv(socketName);
        ......
        if (startSystemServer) {
            //创建启动SystemServer进程
            Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
            ......
        }
        ......
        //等待AMS socket连接,请求fork新进程
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        zygoteServer.closeServerSocket();
    }
    ......
}

ZygoteInit的main函数主要功能:

  • 1.创建Server Socket
  • 2.创建和启动SystemServer进程
  • 3.等待AMS连接socke和发送创建新进程的请求

2.1创建Server Socket

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

void registerServerSocketFromEnv(String socketName) {
    if (mServerSocket == null) {
        ......
        try {
            FileDescriptor fd = new FileDescriptor();
            fd.setInt$(fileDesc);
            mServerSocket = new LocalServerSocket(fd);//创建服务端的Socket
            mCloseSocketFd = true;
        } catch (IOException ex) {
            throw new RuntimeException(
                    "Error binding to local socket '" + fileDesc + "'", ex);
        }
    }
}

创建的LocalServerSocket就是Server端的socket,会在runSelectLoop中调用LocalServerSocket.accept函数等待AMS连接。

2.2启动SystemServer进程

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    ......

    try {
        ......
        //请求fork System Server进程
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.runtimeFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {
        ......
        //启动SystemServer进程
        return handleSystemServerProcess(parsedArgs);
    }

    return null;
}

2.3fork新进程

runSelectLoop函数开启一个守护线程,等待AMS连接或者求情创建进程

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

Runnable runSelectLoop(String abiList) {
    while (true) {
        ......
        for (int i = pollFds.length - 1; i >= 0; --i) {
            ......
            if (i == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);//等待AMS connect
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                try {
                    ZygoteConnection connection = peers.get(i);
                    final Runnable command = connection.processOneCommand(this);//创建新进程
                    ......
                    }
                } catch (Exception e) {
                    ......
                } finally {
                    ......
                }
            }
        }
    }
}

acceptCommandPeer函数最终会调用LocalServerSocket.accept函数等待AMS连接,当AMS连接成功后会调用processOneCommand函数创建新进程。

private ZygoteConnection acceptCommandPeer(String abiList) {
        try {
            return createNewConnection(mServerSocket.accept(), abiList);
        } catch (IOException ex) {
            throw new RuntimeException(
                    "IOException during accept()", ex);
        }
    }

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

Runnable processOneCommand(ZygoteServer zygoteServer) {
    ......
    //fork 进程
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
            parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
            parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
            parsedArgs.instructionSet, parsedArgs.appDataDir);

    try {
        if (pid == 0) {
            // in child
            zygoteServer.setForkChild();

            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;

            return handleChildProc(parsedArgs, descriptors, childPipeFd,
                    parsedArgs.startChildZygote);
        } else {
            // In the parent. A pid < 0 indicates a failure and will be handled in
            // handleParentProc.
            IoUtils.closeQuietly(childPipeFd);
            childPipeFd = null;
            handleParentProc(pid, descriptors, serverPipeFd);
            return null;
        }
    } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
    }
}

三、时序图

在这里插入图片描述

参考资料
https://www.jianshu.com/p/cbc6b84aee08
《Android进阶解密》

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容