zygote64位和system_server进程的启动篇

备注:以下代码均是基于Android8.0分析的,大部分都是精简过的代码,便于理解
先上个流程图和时序图
流程图如下


zygote进程启动过程.png

时序图如下


zygote启动时序图.png

一. init进程以及init.rc解析

init进程是Android的的第一个进程,进程id是1,启动时执行入口main函数,解析init.rc文件,并执行相关的指令

1. init.rc语法和规则

init.rc:是由一种被称为“Android初始化语言”(Android Init Language,这里简称为AIL)的脚本写成的文件,它有自己语法和解析规则init.rc解析

下面看下init.rc的内容,为了方便阅读,给出一个精简版的关键内容

## Copyright (C) 2012 The Android Open Source Project
##
## IMPORTANT: Do not create world writable files or directories.
## This is a common source of Android security bugs.
##

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
##import /init.${ro.zygote}.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main   //option
    priority -20 //option
    user root  //option
    group root readproc
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks、
    
on early-init //监听事件
    *************
on init //监听事件
    *************
on property:sys.boot_from_charger_mode=1 //监听事件
    class_stop charger
    trigger late-init

## Mount filesystems and start core system services.
on late-init //监听事件

    ## Now we can start zygote for devices with file based encryption
    trigger zygote-start  //command
    
on zygote-start && property:ro.crypto.state=unsupported
    ## A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted //command
    start netd //command
    start zygote //command
    start zygote_secondary //command

说明
service关键字表示创建一个服务,
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
表示创建一个名为zygote的服务,其实就是进程,执行文件是/system/bin/app_process64,后面的就是执行时携带参数,这个后续再解析中再讲,注意这只是创建服务,但是还没启动

on是表示监听某些事件,当事件发生触发时,执行下面的指令
比如
on late-init
## Now we can start zygote for devices with file based encryption
trigger zygote-start
表示late-init触发时,触发zygote-start事件

trigger:顾名思义,表示触发某个事件
这样的话
其实大概可以理清zygote在init.rc的启动过程
late-init->zygote-start->start zygote
其中late-init可能是property:sys.boot_from_charger_mode=1触发的,也可能是其他地方触发的,下面的讲解会提到

2. init.rc的解析

下面再看看具体是怎么解析和执行init.rc
精简的关键代码如下
代码路径:system/core/init/init.cpp

int main(int argc, char** argv) {
    //省略代码
     Parser& parser = Parser::GetInstance();
    parser.AddSectionParser("service",std::make_unique<ServiceParser>());
    parser.AddSectionParser("on", std::make_unique<ActionParser>());
    parser.AddSectionParser("import", std::make_unique<ImportParser>());
     //省略代码
     parser.ParseConfig("/init.rc");
     ActionManager& am = ActionManager::GetInstance();

    am.QueueEventTrigger("early-init");
     //省略代码
    // Trigger all the boot actions to get us started.
    am.QueueEventTrigger("init");
     //省略代码

    // Don't mount filesystems or start core system services in charger mode.
    std::string bootmode = GetProperty("ro.bootmode", "");
    if (bootmode == "charger") {
        am.QueueEventTrigger("charger");
    } else {
        am.QueueEventTrigger("late-init");
    }

    // Run all property triggers based on current state of the properties.
    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");

    while (true) {
        // By default, sleep until something happens.
        int epoll_timeout_ms = -1;

        if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
            am.ExecuteOneCommand();
        }
       //省略代码
    }
    return 0;
}

从代码上看,主要分为两部分

2.1 解析

可以看出有三个解析器分别是seriver,on和import,分为解析相关的关键字,这个跟init.rc的结构大体一致

将事件放到队列中,然后按顺序执行,这里面都是执行的初始化相关的事件,包括上面说的late-init这样的话,它就按照init.rc的规则,链式触发相关事件或者执行相关动作

再来看一看parse部分,这里主要看service的parser
先看parse解析器
代码路径:system/core/init/init_parser.cpp

void Parser::ParseData(const std::string& filename, const std::string& data) {
    //TODO: Use a parser with const input and remove this copy
    std::vector<char> data_copy(data.begin(), data.end());
    data_copy.push_back('\0');

    parse_state state;
    state.filename = filename.c_str();
    state.line = 0;
    state.ptr = &data_copy[0];
    state.nexttoken = 0;

    SectionParser* section_parser = nullptr;
    std::vector<std::string> args;

    for (;;) {
        switch (next_token(&state)) {
        case T_EOF:
            if (section_parser) {
                section_parser->EndSection();
            }
            return;
        case T_NEWLINE:
            state.line++;
            if (args.empty()) {
                break;
            }
            if (section_parsers_.count(args[0])) {
                if (section_parser) 
                   //遇到下一个关键字,即该关键字对应的分段解析结束
                    section_parser->EndSection();
                }
               //获取对应关键字的解析器。比如service/on/import
                section_parser = section_parsers_[args[0]].get();
                std::string ret_err;
                //解析关键字对应的行
                if (!section_parser->ParseSection(args, &ret_err)) {
                    parse_error(&state, "%s\n", ret_err.c_str());
                    section_parser = nullptr;
                }
            } else if (section_parser) {
                std::string ret_err;
               //解析关键字下面的内容,也就是init.rc中的option和Commands内容
                if (!section_parser->ParseLineSection(args, state.filename,
                                                      state.line, &ret_err)) {
                    parse_error(&state, "%s\n", ret_err.c_str());
                }
            }
            args.clear();
            break;
        case T_TEXT:
            args.emplace_back(state.text);
            break;
        }
    }
}

代码很简单,解析init.rc里面的内容,遇到关键字是就转给关键字相关的解析器解析

再来看下service的解析器
代码路径:system/core/init/service.cpp

//解析service中option的解析规则,精简代码
Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
    constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
    // clang-format off
    static const Map option_parsers = {
        {"capabilities",
                        {1,     kMax, &Service::ParseCapabilities}},
        {"class",       {1,     kMax, &Service::ParseClass}},
        {"oneshot",     {0,     0,    &Service::ParseOneshot}},
        {"onrestart",   {1,     kMax, &Service::ParseOnrestart}},
    };
    // clang-format on
    return option_parsers;
}


//解析service开头部分,主要是创建个Service
bool ServiceParser::ParseSection(const std::vector<std::string>& args,
                                 std::string* err) {
    if (args.size() < 3) {
        *err = "services must have a name and a program";
        return false;
    }

    const std::string& name = args[1];
    if (!IsValidName(name)) {
        *err = StringPrintf("invalid service name '%s'", name.c_str());
        return false;
    }

    std::vector<std::string> str_args(args.begin() + 2, args.end());
//init.rc的service语法
//service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
//构造一个service,构造参数
//name:zygote
//str_args:/system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    service_ = std::make_unique<Service>(name, str_args);
    return true;
}


//解析option或者comond的内容
/**栗子
  class main
    onrestart write /sys/power/state on
    writepid /dev/cpuset/foreground/tasks
**/
bool ServiceParser::ParseLineSection(const std::vector<std::string>& args,
                                     const std::string& filename, int line,
                                     std::string* err) const {
    return service_ ? service_->ParseLine(args, err) : false;
}

//解析onrestart,就是把option内容分为放在service中对应的数据中,其他的option就不一一列举了
bool Service::ParseOnrestart(const std::vector<std::string>& args, std::string* err) {
    std::vector<std::string> str_args(args.begin() + 1, args.end());
    onrestart_.AddCommand(str_args, "", 0, err);
    return true;
}

//service关键字解析结束,将service加到vector容器中
void ServiceParser::EndSection() {
    if (service_) {
        ServiceManager::GetInstance().AddService(std::move(service_));
    }
}
至此service的部分解析结束

2.2 触发事件

am.QueueEventTrigger("early-init");
am.QueueEventTrigger("init");
am.QueueEventTrigger("late-init");
am.ExecuteOneCommand();

二. zygote服务(进程)的启动

1. 相关数据结构

从第一章节的2.2小节可以看到,解析完成之后触发一些事件,对于zygote而言,init.rc里面有如下指令

on late-init
    ## Now we can start zygote for devices with file based encryption
    trigger zygote-start
on zygote-start && property:ro.crypto.state=unsupported
    start zygote
    start zygote_secondary

也就是说late-init事件发生时,会再触发一个zygote-start事件,继续触发start zygote指令

先看下相关的数据结构,精简代码
代码路径:system/core/init/action.cpp
class Action

class Action {
private:
    std::string event_trigger_;  
    std::vector<Command> commands_;
    static const KeywordMap<BuiltinFunction>* function_map_;
};


class Command {
private:
    BuiltinFunction func_;
    std::vector<std::string> args_;
    std::string filename_;
    int line_;
};

class action中
event_trigger_:该action监听的触发器
Command:触发器触发后要做的指令
function_map_:维护一个指令与具体调用方法的映射关系

class Command中
func_:具体的方法指针,通过解析on关键字,将指令取出(比如start指令),然后通过function_map_拿到具体的方法指针
args_:数据

如下是具体指令与具体调用方法的映射关系的精简代码,我们只需关注start指令就行
代码路径:system/core/init/builtins.cpp

BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
    constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
    // clang-format off
    static const Map builtin_functions = {
        {"bootchart",               {1,     1,    do_bootchart}},
        {"chmod",                   {2,     2,    do_chmod}},
        {"chown",                   {2,     3,    do_chown}},
        {"class_reset",             {1,     1,    do_class_reset}},
        {"class_restart",           {1,     1,    do_class_restart}},
        {"class_start",             {1,     1,    do_class_start}},
        {"class_stop",              {1,     1,    do_class_stop}},
        {"start",                   {1,     1,    do_start}},
    };
    // clang-format on
    return builtin_functions;
}

2. init进程触发事件过程

代码路径:system/core/init/action.cpp
精简代码

void ActionManager::ExecuteOneCommand() {
    // Loop through the trigger queue until we have an action to execute
   //遍历trigger队列与action中的监听trigger对比
    while (current_executing_actions_.empty() && !trigger_queue_.empty()) {
        for (const auto& action : actions_) {
            if (trigger_queue_.front()->CheckTriggers(*action)) {
                current_executing_actions_.emplace(action.get());
            }
        }
        trigger_queue_.pop();
    }
     //命中的话,执行相关指令
    action->ExecuteOneCommand(current_command_);
}

void Action::ExecuteOneCommand(std::size_t command) const {
    // We need a copy here since some Command execution may result in
    // changing commands_ vector by importing .rc files through parser
    Command cmd = commands_[command];
    ExecuteCommand(cmd);
}

void Action::ExecuteCommand(const Command& command) const {
    Timer t;
    int result = command.InvokeFunc();
}

 //执行指令对应的函数
int Command::InvokeFunc() const {
    expanded_args[0] = args_[0];
    return func_(expanded_args);
}

3.开始启动zygote 服务

3.1 do_start()

上面func_(expanded_args)其实就是执行do_start
代码路径:system/core/init/builtins.cpp

static int do_start(const std::vector<std::string>& args) {
    //args是init.rc对应的start zygote指令
    //args[1]就是zygote了,根据上面2.1章节解析service时会把结果放在vector容器中,而且service里面有name的成员变量
    //由此还可以根据name拿到对应的service
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    if (!svc) {
        LOG(ERROR) << "do_start: Service " << args[1] << " not found";
        return -1;
    }
//调用service的start方法
    if (!svc->Start())
        return -1;
    return 0;
}

3.2 Start()

代码路径:system/core/init/service.cpp

bool Service::Start() {
    pid_t pid = -1;
    if (namespace_flags_) {
        pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
    } else {
        //熟悉的fork代码
        pid = fork();
    }

    if (pid == 0) {
        std::vector<char*> strs;
        ExpandArgs(args_, &strs);
       //strs[0]就是/system/bin/app_process64
        //将fork出来的子进程也就是zygote进程变身到一个新的进程,pid和进程名保持不变,其他的数据被新的进程覆盖
        if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
            PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
        }

        _exit(127);
    }

    if (pid < 0) {
        PLOG(ERROR) << "failed to fork for '" << name_ << "'";
        pid_ = 0;
        return false;
    }
    return true;
}

说明:
1./system/bin/app_process6是有app_main.cpp编译的可执行文件
2.execve() 调用 成功 后 不会 返回, 其 进程 的 正文(text), 数据(data), bss 和 堆栈(stack) 段
被 调入程序 覆盖. 调入程序 继承了 调用程序 的 PID 和 所有 打开的 文件描述符, 他们 不会
因为 exec 过程 而 关闭. 父进程 的 未决 信号 被 清除. 所有 被 调用进程 设置过 的 信号
重置为 缺省行为
也就是说execve如果调用成功,其后面的代码不会被执行

3.3 app_main的main()

代码路径:frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
   //AppRuntime是继承AndroidRuntime的,这里创建一个runtime,下文会提及到 //todo_1
   AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            //zygote的进程名zygote64
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //启动system_server进程,也就是说zygote启动后就去fork出system_server进程
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    if (!niceName.isEmpty()) {
        //设置zygote的进程名
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }

    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.");
    }
}

3.4 AndroidRuntime.start()

代码路径:frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动虚拟机
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.注册native方法
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            //调用ZygoteInit的入口函数main
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);

    ALOGD("Shutting down VM\n");
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        ALOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        ALOGW("Warning: VM did not shut down cleanly\n");
}

说明:AndroidRuntime.start()主要做了三件事
1.注册framework层的native方法以便jni调用,比如com_android_internal_os_ZygoteInit_nativeZygoteInit
2.启动虚拟机
3.调用ZygoteInit.java 的main函数,这个main一直会执行或者阻塞,不会退出,这样的话VM也不会退出

3.5 ZygoteInit.main()

代码路径ZygoteInit.java

   public static void main(String argv[]) {
       ZygoteServer zygoteServer = new ZygoteServer();

           // Start profiling the zygote initialization.
           SamplingProfilerIntegration.start();

           boolean startSystemServer = false;
           String socketName = "zygote";
           String abiList = null;
           boolean enableLazyPreload = false;
           for (int i = 1; i < argv.length; i++) {
               if ("start-system-server".equals(argv[i])) {
                  //标识启动system_server进程
                   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]);
               }
           }
           if (abiList == null) {
               throw new RuntimeException("No ABI list supplied.");
           }
           //注册一个socket server
           zygoteServer.registerServerSocket(socketName);
           // In some configurations, we avoid preloading resources and classes eagerly.
           // In such cases, we will preload things prior to our first fork.
          preload(bootTimingsTraceLog);

           // Finish profiling the zygote initialization.
           SamplingProfilerIntegration.writeZygoteSnapshot();

           // Do an initial gc to clean up after startup
           bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
           gcAndFinalize();
           bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

           if (startSystemServer) {
              //启动system_server进程 
               startSystemServer(abiList, socketName, zygoteServer);
           }

           Log.i(TAG, "Accepting command socket connections");
          //开始在while循环中监听来自AMS的fork子进程的请求,避免main退出
           zygoteServer.runSelectLoop(abiList);

           zygoteServer.closeServerSocket();
       } catch (Zygote.MethodAndArgsCaller caller) {
           caller.run();
       } catch (Throwable ex) {
           Log.e(TAG, "System zygote died with exception", ex);
           zygoteServer.closeServerSocket();
           throw ex;
       }
   }

说明:main主要做了三件事
1.preload 预加载
预加载framework中的类(/system/etc/
preloaded-classes)
预加载framework中的资源/system/framework/framework-res.apk
预加载动态库libandroid.so,libjnigraphics.so等等
预加载动态库libandroid.so,libjnigraphics.so等等
预加载默认字体
2.启动system_server进程
3.注册socket server并在循环中监听来自system_server的fork子进程的请求,

三 system_server进程的启动

1.1 startSystemServer

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        String args[] = {
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            zygoteServer.closeServerSocket();
           //fork成功,处理system_server
            handleSystemServerProcess(parsedArgs);
        }
        return true;
    }

    /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {

        if (parsedArgs.niceName != null) {
            //设置进程名
            Process.setArgV0(parsedArgs.niceName);
        }
            /*
             * Pass the remaining arguments to SystemServer.
             */
           //这里是被zygote进程fork出来的子进程做的一些初始化工作(主要是System_server进程和普通的app进程)
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        /* should never reach here */
    }

1.2 ZygoteInit.zygoteInit

代码路径:ZygoteInit.java

 public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        //通过jni调用native的方法,在5.4 AndroidRuntime.start()中提过的,注册了jni相关函数以便java端的调用,这里正好用到了
        ZygoteInit.nativeZygoteInit();
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

说明:zygoteInit主要做了三件事
1.RuntimeInit.commonInit() 设置UncaughtExceptionhandler和UA,具体代码比较简单这里不列举了
2.ZygoteInit.nativeZygoteInit() 调用native端的ZygoteInit(),这稍后再说
3.RuntimeInit.applicationInit 根据argv找到启动类,并执行入口main函数,具体代码比较简单这里不列举了(其实就是反射调用啦)

1.3 ZygoteInit.nativeZygoteInit()

代码路径frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

这个gCurRuntime实际就是5.3 app_main.cpp main中创建的appruntime ,可以查看todo_1标签与之呼应

1.4 onZygoteInit()

代码路径frameworks/base/cmds/app_process/app_main.cpp

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

说明:ProcessState是进程的状态,在构造函数时,会打开binder驱动做内存映射,startThreadPool会启动一个binder主线程,这样system_server具备binder的能力也就是跨进程通信的能力,app进程也是这样的,在创建成功后也会构造一个ProcessState,
另外我们可以看到zygote进程在启动的过程中并没有去创建ProcessState,所以zygote并没有binder的能力,所以zygote与system_server通信时用的是socket,至于zygote为什么不用binder
待下回分解。
至此所有的流程分析完毕。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271