Android

Zygote底层启动流程简单分析

2018-04-28  本文已影响0人  Spirituality韬

Zygote的启动

Android大部分应用程序和系统进程都是通过Zygote来生成的
源码下
/system/core/rootdir/init.rc

import /init.${ro.zygote}.rc     #根据32和64位机器区分

其中对init.zygote32.rc分析

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    ...
   writepid /dev/cpuset/foreground/tasks

从zygote的path可以看出,他所在的程序名叫“app_process”,对整个Android源码搜索找到/frameworks/base/cmds/app_process这个目录下,该目录下的app_main.cpp中main函数可以,通过init.zygote32.rc传递的参数来启动

  ...... --zygote --start-system-server
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.");
}

app_process将启动"ZygoteInit"并且启动system server。runtime实际是一个AndroidRuntime对象,其start在源码/frameworks/base/core/jni/AndroidRuntime.cpp文件中

if (startVm(&mJavaVM, &env, zygote) != 0) {
    return;
}
onVmCreated(env);

这条语句启动Java虚拟机,启动成功在进入/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中执行。

ZygoteInit.java

public static void main(String argv[]) {
    ...
    //通过上面传进来的参数来设置执行逻辑
    for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {
                startSystemServer = true;
            } else if ("--enable-lazy-preload".equals(argv[i])) {
                enableLazyPreload = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                socketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }
    //注册zygote服务端Socket对象
    zygoteServer.registerServerSocket(socketName);
    if (!enableLazyPreload) {
          preload(bootTimingsTraceLog);
     }
     ...
    if (startSystemServer) {
        startSystemServer(abiList, socketName, zygoteServer);
    }
    Log.i(TAG, "Accepting command socket connections");
    //
    zygoteServer.runSelectLoop(abiList);
    zygoteServer.closeServerSocket();
    ...
 }

通过main函数可以知道 ZygoteInit利用ZygoteServer为zygote命令连接注册一个服务器套接字,一旦一个程序需要运行时,系统会通过这个Socket在第一时间通知“总管家”,并由它负责实际的进程孵化过程。
从传递的参数来看这些都是执行得
1.预加载虚拟机运行时所需要的各类资源preload(bootTimingsTraceLog);
2.利用UNIX的fork机制SystemServer(下章),从代码上看新建一个专门的进程来承载系统服务的运行。
3.zygoteServer.runSelectLoop这是一个死循环(Socket通信中不陌生),作为zygote的守护主体。
ZygoteServer.java

 void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

    fds.add(mServerSocket.getFileDescriptor());
    peers.add(null);

    while (true) {
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        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 {
                boolean done = peers.get(i).runOnce(this);
                if (done) {
                    peers.remove(i);
                    fds.remove(i);
                }
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读