返回

揭秘Zygote进程启动源码,解锁Android应用进程启动机制

Android

Zygote,Android进程启动的基石

在Android系统中,Zygote进程扮演着至关重要的角色,它是Android系统中第一个被创建的进程,也是所有其他进程的祖先。Android中的System Server进程、应用进程都是通过Zygote进程fork而来,因此了解Zygote进程的启动流程源码,对理解Android系统的进程管理和应用启动机制至关重要。

一、启动Zygote进程

Zygote进程的启动过程主要由init进程负责,init进程是Android系统启动的第一个进程,它负责初始化系统环境,启动Zygote进程是init进程的重要任务之一。

void init_set_zygote_args(const char *arg_list, int pid, int socket_pair[2])
{
    char *args, *args_next, *args_prev;
    char *saved_args = strdup(arg_list);
    size_t len;

    args = saved_args;

    while (1) {
        args_next = strchr(args, ' ');
        if (!args_next) break;

        args_prev = args;
        len = args_next - args;
        args = args_next + 1;

        if (len == 5 && !memcmp(args_prev, "debug", 5)) {
            fcntl(socket_pair[1], F_SETFD, FD_CLOEXEC);
            close(socket_pair[1]);
            socket_pair[1] = -1;

            return;
        }
    }
    free(saved_args);
}

在init进程中,会调用init_set_zygote_args()函数,对Zygote进程的启动参数进行设置,包括是否开启调试模式等。

int main(int argc, char **argv)
{
    pid_t pid;
    int socket_pair[2];
    int status;

    if (prctl(PR_SET_NAME, "zygote", 0, 0, 0) < 0) {
        exit(1);
    }

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair)) {
        exit(1);
    }

    pid = fork();
    if (pid == -1) {
        exit(1);
    }

    if (pid == 0) {
        close(socket_pair[1]);
        init_set_zygote_args(argv[1], getpid(), socket_pair);
        if (zygote_process(socket_pair[0]) < 0) {
            exit(1);
        }
    } else {
        close(socket_pair[0]);
        if (waitpid(pid, &status, 0) < 0) {
            exit(1);
        }

        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
            exit(0);
        } else {
            exit(1);
        }
    }

    return 0;
}

随后,init进程会调用fork()函数,创建一个子进程,也就是Zygote进程。在Zygote进程中,会调用zygote_process()函数,正式启动Zygote进程。

二、Zygote进程的启动流程

Zygote进程启动后,会执行一系列初始化操作,包括:

  • 加载系统库
  • 创建线程池
  • 初始化Binder系统
  • 加载应用框架
  • 启动System Server进程
static int zygote_process(int fd)
{
    int ret;

    ret = selinux_restore_domainfile("/file_contexts");
    if (ret < 0) {
        zygote_log(LOG_ERR, "selinux_restore_domainfile() failed: %s\n", strerror(errno));
        return -1;
    }

    /* Load the system properties, they are needed by various components. */
    ret = property_load_boot_defaults();
    if (ret) {
        zygote_log(LOG_ERR, "property_load_boot_defaults() failed: %s\n", strerror(errno));
        return -1;
    }

    /* Default umask when starting applications. This can be overridden on a per-app
     * basis with SELinux. */
    umask(0027);

    /* set the umask so that SELinux doesn't relabel the temp file created
     * in zygote_read_apk_from_file() to u:object_r:apk_data_file:s0 */
    umask(000);

    ret = prepare_data_fd(fd);
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_data_fd() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_argv0();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_argv0() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_env();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_env() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_debuggerd_zygote();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_debuggerd_zygote() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_property_service();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_property_service() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_openjdkjvm();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_openjdkjvm() failed: %s\n", strerror(errno));
        return -1;
    }

    /* Stash a pointer to ZygoteProcess in ZygoteState so it can be retrieved by
     * system_server. */
    zygote_state->zygote_process = zygote_process;

    ret = prepare_zygote_socket();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_zygote_socket() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_app_process_limit();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_app_process_limit() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_libraries();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_libraries() failed: %s\n", strerror(errno));
        return -1;
    }

    ret = prepare_system_server();
    if (ret < 0) {
        zygote_log(LOG_ERR, "prepare_system_server() failed: %s\n", strerror(errno));
        return -1;
    }

    zygote_atexit();

    if (start_system_server() < 0) {
        zygote_log(LOG_ERR, "starting system server failed: %s\n", strerror(errno));
        return -1;
    }

    if (zygote_child_init() < 0) {
        zygote_log(LOG_ERR, "zygote_child_init() failed: %s\n", strerror(errno));
        return -1;
    }

    /* get the current umask. This is used to restore the umask of the child process
     * after exec() */
    umask(old_umask);

    return 0;
}

在完成初始化操作后,Zygote进程会进入主循环,等待来自客户端的请求。当客户端请求启动一个新的应用进程时,Zygote进程会调用fork()函数,创建一个子进程,也就是新的应用进程。

三、Zygote进程的职责

Zygote进程在Android系统中扮演着重要的角色,主要负责以下职责:

  • 加载系统库: Zygote进程会加载必要的系统库,为应用进程提供基础环境。
  • 创建线程池: Zygote进程会创建线程池,为应用进程提供多线程支持。
  • 初始化Binder系统: Zygote进程会初始化Binder系统,为应用进程提供跨进程通信机制。
  • 加载应用框架: Zygote进程会加载应用框架,为应用进程提供基本功能和服务。
  • **启动System Server进程