zygote64位和system_server進(jìn)程的啟動(dòng)篇

備注:以下代碼均是基于Android8.0分析的,大部分都是精簡(jiǎn)過(guò)的代碼,便于理解
先上個(gè)流程圖和時(shí)序圖
流程圖如下


zygote進(jìn)程啟動(dòng)過(guò)程.png

時(shí)序圖如下


zygote啟動(dòng)時(shí)序圖.png

一. init進(jìn)程以及init.rc解析

init進(jìn)程是Android的的第一個(gè)進(jìn)程算利,進(jìn)程id是1啼染,啟動(dòng)時(shí)執(zhí)行入口main函數(shù)趟紊,解析init.rc文件竹海,并執(zhí)行相關(guān)的指令

1. init.rc語(yǔ)法和規(guī)則

init.rc:是由一種被稱為“Android初始化語(yǔ)言”(Android Init Language晰骑,這里簡(jiǎn)稱為AIL)的腳本寫(xiě)成的文件敛劝,它有自己語(yǔ)法和解析規(guī)則init.rc解析

下面看下init.rc的內(nèi)容,為了方便閱讀余爆,給出一個(gè)精簡(jiǎn)版的關(guān)鍵內(nèi)容

## 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 //監(jiān)聽(tīng)事件
    *************
on init //監(jiān)聽(tīng)事件
    *************
on property:sys.boot_from_charger_mode=1 //監(jiān)聽(tīng)事件
    class_stop charger
    trigger late-init

## Mount filesystems and start core system services.
on late-init //監(jiān)聽(tīng)事件

    ## 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

說(shuō)明
service關(guān)鍵字表示創(chuàng)建一個(gè)服務(wù)夸盟,
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
表示創(chuàng)建一個(gè)名為zygote的服務(wù)蛾方,其實(shí)就是進(jìn)程,執(zhí)行文件是/system/bin/app_process64,后面的就是執(zhí)行時(shí)攜帶參數(shù)桩砰,這個(gè)后續(xù)再解析中再講拓春,注意這只是創(chuàng)建服務(wù),但是還沒(méi)啟動(dòng)

on是表示監(jiān)聽(tīng)某些事件亚隅,當(dāng)事件發(fā)生觸發(fā)時(shí)痘儡,執(zhí)行下面的指令
比如
on late-init
## Now we can start zygote for devices with file based encryption
trigger zygote-start
表示late-init觸發(fā)時(shí),觸發(fā)zygote-start事件

trigger:顧名思義枢步,表示觸發(fā)某個(gè)事件
這樣的話
其實(shí)大概可以理清zygote在init.rc的啟動(dòng)過(guò)程
late-init->zygote-start->start zygote
其中l(wèi)ate-init可能是property:sys.boot_from_charger_mode=1觸發(fā)的沉删,也可能是其他地方觸發(fā)的,下面的講解會(huì)提到

2. init.rc的解析

下面再看看具體是怎么解析和執(zhí)行init.rc
精簡(jiǎn)的關(guān)鍵代碼如下
代碼路徑: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 解析

可以看出有三個(gè)解析器分別是seriver矾瑰,on和import,分為解析相關(guān)的關(guān)鍵字隘擎,這個(gè)跟init.rc的結(jié)構(gòu)大體一致

將事件放到隊(duì)列中殴穴,然后按順序執(zhí)行,這里面都是執(zhí)行的初始化相關(guān)的事件货葬,包括上面說(shuō)的late-init這樣的話采幌,它就按照init.rc的規(guī)則,鏈?zhǔn)接|發(fā)相關(guān)事件或者執(zhí)行相關(guān)動(dòng)作

再來(lái)看一看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) 
                   //遇到下一個(gè)關(guān)鍵字休傍,即該關(guān)鍵字對(duì)應(yīng)的分段解析結(jié)束
                    section_parser->EndSection();
                }
               //獲取對(duì)應(yīng)關(guān)鍵字的解析器。比如service/on/import
                section_parser = section_parsers_[args[0]].get();
                std::string ret_err;
                //解析關(guān)鍵字對(duì)應(yīng)的行
                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;
               //解析關(guān)鍵字下面的內(nèi)容蹲姐,也就是init.rc中的option和Commands內(nèi)容
                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;
        }
    }
}

代碼很簡(jiǎn)單磨取,解析init.rc里面的內(nèi)容,遇到關(guān)鍵字是就轉(zhuǎn)給關(guān)鍵字相關(guān)的解析器解析

再來(lái)看下service的解析器
代碼路徑:system/core/init/service.cpp

//解析service中option的解析規(guī)則柴墩,精簡(jiǎn)代碼
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開(kāi)頭部分忙厌,主要是創(chuàng)建個(gè)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語(yǔ)法
//service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
//構(gòu)造一個(gè)service,構(gòu)造參數(shù)
//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的內(nèi)容
/**栗子
  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內(nèi)容分為放在service中對(duì)應(yīng)的數(shù)據(jù)中江咳,其他的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關(guān)鍵字解析結(jié)束逢净,將service加到vector容器中
void ServiceParser::EndSection() {
    if (service_) {
        ServiceManager::GetInstance().AddService(std::move(service_));
    }
}
至此service的部分解析結(jié)束

2.2 觸發(fā)事件

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

二. zygote服務(wù)(進(jìn)程)的啟動(dòng)

1. 相關(guān)數(shù)據(jù)結(jié)構(gòu)

從第一章節(jié)的2.2小節(jié)可以看到,解析完成之后觸發(fā)一些事件,對(duì)于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

也就是說(shuō)late-init事件發(fā)生時(shí)爹土,會(huì)再觸發(fā)一個(gè)zygote-start事件,繼續(xù)觸發(fā)start zygote指令

先看下相關(guān)的數(shù)據(jù)結(jié)構(gòu)东臀,精簡(jiǎn)代碼
代碼路徑: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監(jiān)聽(tīng)的觸發(fā)器
Command:觸發(fā)器觸發(fā)后要做的指令
function_map_:維護(hù)一個(gè)指令與具體調(diào)用方法的映射關(guān)系

class Command中
func_:具體的方法指針着饥,通過(guò)解析on關(guān)鍵字,將指令取出(比如start指令)惰赋,然后通過(guò)function_map_拿到具體的方法指針
args_:數(shù)據(jù)

如下是具體指令與具體調(diào)用方法的映射關(guān)系的精簡(jiǎn)代碼宰掉,我們只需關(guān)注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進(jìn)程觸發(fā)事件過(guò)程

代碼路徑:system/core/init/action.cpp
精簡(jiǎn)代碼

void ActionManager::ExecuteOneCommand() {
    // Loop through the trigger queue until we have an action to execute
   //遍歷trigger隊(duì)列與action中的監(jiān)聽(tīng)trigger對(duì)比
    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();
    }
     //命中的話呵哨,執(zhí)行相關(guān)指令
    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();
}

 //執(zhí)行指令對(duì)應(yīng)的函數(shù)
int Command::InvokeFunc() const {
    expanded_args[0] = args_[0];
    return func_(expanded_args);
}

3.開(kāi)始啟動(dòng)zygote 服務(wù)

3.1 do_start()

上面func_(expanded_args)其實(shí)就是執(zhí)行do_start
代碼路徑:system/core/init/builtins.cpp

static int do_start(const std::vector<std::string>& args) {
    //args是init.rc對(duì)應(yīng)的start zygote指令
    //args[1]就是zygote了,根據(jù)上面2.1章節(jié)解析service時(shí)會(huì)把結(jié)果放在vector容器中轨奄,而且service里面有name的成員變量
    //由此還可以根據(jù)name拿到對(duì)應(yīng)的service
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    if (!svc) {
        LOG(ERROR) << "do_start: Service " << args[1] << " not found";
        return -1;
    }
//調(diào)用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出來(lái)的子進(jìn)程也就是zygote進(jìn)程變身到一個(gè)新的進(jìn)程孟害,pid和進(jìn)程名保持不變,其他的數(shù)據(jù)被新的進(jìn)程覆蓋
        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;
}

說(shuō)明:
1./system/bin/app_process6是有app_main.cpp編譯的可執(zhí)行文件
2.execve() 調(diào)用 成功 后 不會(huì) 返回, 其 進(jìn)程 的 正文(text), 數(shù)據(jù)(data), bss 和 堆棧(stack) 段
被 調(diào)入程序 覆蓋. 調(diào)入程序 繼承了 調(diào)用程序 的 PID 和 所有 打開(kāi)的 文件描述符, 他們 不會(huì)
因?yàn)? exec 過(guò)程 而 關(guān)閉. 父進(jìn)程 的 未決 信號(hào) 被 清除. 所有 被 調(diào)用進(jìn)程 設(shè)置過(guò) 的 信號(hào)
重置為 缺省行為
也就是說(shuō)execve如果調(diào)用成功挪拟,其后面的代碼不會(huì)被執(zhí)行

3.3 app_main的main()

代碼路徑:frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
   //AppRuntime是繼承AndroidRuntime的,這里創(chuàng)建一個(gè)runtime挨务,下文會(huì)提及到 //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的進(jìn)程名zygote64
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //啟動(dòng)system_server進(jìn)程,也就是說(shuō)zygote啟動(dòng)后就去fork出system_server進(jìn)程
            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()) {
        //設(shè)置zygote的進(jìn)程名
        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;
    //啟動(dòng)虛擬機(jī)
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.注冊(cè)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 {
            //調(diào)用ZygoteInit的入口函數(shù)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");
}

說(shuō)明:AndroidRuntime.start()主要做了三件事
1.注冊(cè)framework層的native方法以便jni調(diào)用玉组,比如com_android_internal_os_ZygoteInit_nativeZygoteInit
2.啟動(dòng)虛擬機(jī)
3.調(diào)用ZygoteInit.java 的main函數(shù)谎柄,這個(gè)main一直會(huì)執(zhí)行或者阻塞,不會(huì)退出惯雳,這樣的話VM也不會(huì)退出

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])) {
                  //標(biāo)識(shí)啟動(dòng)system_server進(jìn)程
                   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.");
           }
           //注冊(cè)一個(gè)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) {
              //啟動(dòng)system_server進(jìn)程 
               startSystemServer(abiList, socketName, zygoteServer);
           }

           Log.i(TAG, "Accepting command socket connections");
          //開(kāi)始在while循環(huán)中監(jiān)聽(tīng)來(lái)自AMS的fork子進(jìn)程的請(qǐng)求朝巫,避免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;
       }
   }

說(shuō)明:main主要做了三件事
1.preload 預(yù)加載
預(yù)加載framework中的類(/system/etc/
preloaded-classes)
預(yù)加載framework中的資源/system/framework/framework-res.apk
預(yù)加載動(dòng)態(tài)庫(kù)libandroid.so,libjnigraphics.so等等
預(yù)加載動(dòng)態(tài)庫(kù)libandroid.so石景,libjnigraphics.so等等
預(yù)加載默認(rèn)字體
2.啟動(dòng)system_server進(jìn)程
3.注冊(cè)socket server并在循環(huán)中監(jiān)聽(tīng)來(lái)自system_server的fork子進(jìn)程的請(qǐng)求劈猿,

三 system_server進(jìn)程的啟動(dòng)

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) {
            //設(shè)置進(jìn)程名
            Process.setArgV0(parsedArgs.niceName);
        }
            /*
             * Pass the remaining arguments to SystemServer.
             */
           //這里是被zygote進(jìn)程fork出來(lái)的子進(jìn)程做的一些初始化工作(主要是System_server進(jìn)程和普通的app進(jìn)程)
            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();
        //通過(guò)jni調(diào)用native的方法潮孽,在5.4 AndroidRuntime.start()中提過(guò)的揪荣,注冊(cè)了jni相關(guān)函數(shù)以便java端的調(diào)用,這里正好用到了
        ZygoteInit.nativeZygoteInit();
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

說(shuō)明:zygoteInit主要做了三件事
1.RuntimeInit.commonInit() 設(shè)置UncaughtExceptionhandler和UA往史,具體代碼比較簡(jiǎn)單這里不列舉了
2.ZygoteInit.nativeZygoteInit() 調(diào)用native端的ZygoteInit()仗颈,這稍后再說(shuō)
3.RuntimeInit.applicationInit 根據(jù)argv找到啟動(dòng)類,并執(zhí)行入口main函數(shù)怠堪,具體代碼比較簡(jiǎn)單這里不列舉了(其實(shí)就是反射調(diào)用啦)

1.3 ZygoteInit.nativeZygoteInit()

代碼路徑frameworks/base/core/jni/AndroidRuntime.cpp

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

這個(gè)gCurRuntime實(shí)際就是5.3 app_main.cpp main中創(chuàng)建的appruntime ,可以查看todo_1標(biāo)簽與之呼應(yīng)

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();
    }

說(shuō)明:ProcessState是進(jìn)程的狀態(tài)揽乱,在構(gòu)造函數(shù)時(shí),會(huì)打開(kāi)binder驅(qū)動(dòng)做內(nèi)存映射粟矿,startThreadPool會(huì)啟動(dòng)一個(gè)binder主線程,這樣system_server具備binder的能力也就是跨進(jìn)程通信的能力损拢,app進(jìn)程也是這樣的陌粹,在創(chuàng)建成功后也會(huì)構(gòu)造一個(gè)ProcessState,
另外我們可以看到zygote進(jìn)程在啟動(dòng)的過(guò)程中并沒(méi)有去創(chuàng)建ProcessState福压,所以zygote并沒(méi)有binder的能力掏秩,所以zygote與system_server通信時(shí)用的是socket,至于zygote為什么不用binder
待下回分解。
至此所有的流程分析完畢荆姆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蒙幻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胆筒,更是在濱河造成了極大的恐慌邮破,老刑警劉巖诈豌,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異抒和,居然都是意外死亡矫渔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)摧莽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)庙洼,“玉大人,你說(shuō)我怎么就攤上這事镊辕∮凸唬” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵征懈,是天一觀的道長(zhǎng)石咬。 經(jīng)常有香客問(wèn)我,道長(zhǎng)受裹,這世上最難降的妖魔是什么碌补? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮棉饶,結(jié)果婚禮上厦章,老公的妹妹穿的比我還像新娘。我一直安慰自己照藻,他們只是感情好袜啃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著幸缕,像睡著了一般群发。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上发乔,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天熟妓,我揣著相機(jī)與錄音,去河邊找鬼栏尚。 笑死起愈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的译仗。 我是一名探鬼主播抬虽,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纵菌!你這毒婦竟也來(lái)了阐污?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤咱圆,失蹤者是張志新(化名)和其女友劉穎笛辟,沒(méi)想到半個(gè)月后功氨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隘膘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年疑故,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弯菊。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纵势,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出管钳,到底是詐尸還是另有隱情钦铁,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布才漆,位于F島的核電站牛曹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏醇滥。R本人自食惡果不足惜黎比,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸳玩。 院中可真熱鬧阅虫,春花似錦、人聲如沸不跟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)窝革。三九已至购城,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間虐译,已是汗流浹背瘪板。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漆诽,地道東北人篷帅。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拴泌,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惊橱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345