Android FrameWork详细教程—第一个启动的程序--init 与 Zygote
第一个启动的程序–init
不管Java还是C++运行一个程序都是以main方法作为入口。所以我们先看看init.cpp的main函数.
目录:/system/core/init/main.cpp
具体代码:
int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)__asan_set_error_report_callback(AsanReportCallback);
#endifif (!strcmp(basename(argv[0]), "ueventd")) {return ueventd_main(argc, argv);}if (argc > 1) {if (!strcmp(argv[1], "subcontext")) {android::base::InitLogging(argv, &android::base::KernelLogger);const BuiltinFunctionMap function_map;return SubcontextMain(argc, argv, &function_map);}if (!strcmp(argv[1], "selinux_setup")) {return SetupSelinux(argv);}if (!strcmp(argv[1], "second_stage")) {return SecondStageMain(argc, argv);//}}return FirstStageMain(argc, argv);//在这里创建和挂载了启动所需要的目录信息包含tmpfs、devpts、proc、sysfs、selinuxfs文件系统。。
}
在Main函数,分了几个阶段,首先第一步是FirstStageMain
,我们看看他做了什么?
目录:/system/core/init/first_stage_init.cpp
具体代码:
int FirstStageMain(int argc, char** argv) {if (REBOOT_BOOTLOADER_ON_PANIC) {InstallRebootSignalHandlers();}boot_clock::time_point start_time = boot_clock::now();std::vector<std::pair<std::string, int>> errors;
#define CHECKCALL(x) \\if ((x) != 0) errors.emplace_back(#x " failed", errno);// Clear the umask.umask(0);CHECKCALL(clearenv());CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));// Get the basic filesystem setup we need put together in the initramdisk// on / and then we'll let the rc file figure out the rest.CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));//挂载了tmpfsCHECKCALL(mkdir("/dev/pts", 0755));//创建pts目录并且赋予0755的权限CHECKCALL(mkdir("/dev/socket", 0755));//创建socket目录并且赋予0755的权限CHECKCALL(mkdir("/dev/dm-user", 0755));//创建dm-user目录并且赋予0755的权限CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));//挂载devpts
#define MAKE_STR(x) __STRING(x)CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));//挂载proc文件系统
#undef MAKE_STR// Don't expose the raw commandline to unprivileged processes.CHECKCALL(chmod("/proc/cmdline", 0440));std::string cmdline;android::base::ReadFileToString("/proc/cmdline", &cmdline);// Don't expose the raw bootconfig to unprivileged processes.chmod("/proc/bootconfig", 0440);std::string bootconfig;android::base::ReadFileToString("/proc/bootconfig", &bootconfig);gid_t groups[] = {AID_READPROC};CHECKCALL(setgroups(arraysize(groups), groups));CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));//挂载sysfsCHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));//挂载selinxfsCHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));if constexpr (WORLD_WRITABLE_KMSG) {CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)));}CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,"mode=0755,uid=0,gid=1000"));CHECKCALL(mkdir("/mnt/vendor", 0755));CHECKCALL(mkdir("/mnt/product", 0755));CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,"mode=0755,uid=0,gid=0"));CHECKCALL(mount("tmpfs", kSecondStageRes, "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,"mode=0755,uid=0,gid=0"))
#undef CHECKCALLSetStdioToDevNull(argv);InitKernelLogging(argv);const char* path = "/system/bin/init";const char* args[] = {path, "selinux_setup", nullptr};auto fd = open("/dev/kmsg", O_WRONLY | O_CLOEXEC);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);close(fd);execv(path, const_cast<char**>(args));// execv() only returns if an error happened, in which case we// panic and never fall through this conditional.PLOG(FATAL) << "execv(\\"" << path << "\\") failed";return 1;
}
原来init进程的第一个阶段主要是挂载了tmpfs、devpts、proc、sysfs和selinux 文件系统,也就是说android系统启动就挂载了,关闭就消失了。
其中文件系统:
1.tmpfs:虚拟文件系统,他把所有的文件都存在虚拟内存中。tmpfs速度很快,毕竟他是驻留在RAM中。但是由于驻留在RAM中,所以断电之后文件内容不会被保存。
2.devpts:管理远程虚拟终端文件设备,挂接点是/dev/pts。pty的主复合设备/dev/ptmx被打开,就会在/dev/pts下创建pty设备文件。
3.proc:非常重要的虚拟文件系统,,通过它我们可以获得系统信息,同时也能够在运行时修改特定的内核参数。
4.sysfs:和proc类似,把连接在系统上的设备和总线组织成一个分级的文件,使得它们可以在用户空间存取。
5.selinux:对系统中每一个对象都生成一个安全上下文,每个对象访问系统资源都需要进行上下文审查。
再挂在完成之后,又返回了init 启动了selinux_setup。
int SetupSelinux(char argv) {SetStdioToDevNull(argv);InitKernelLogging(argv);if (REBOOT_BOOTLOADER_ON_PANIC) {InstallRebootSignalHandlers();}boot_clock::time_point start_time = boot_clock::now();MountMissingSystemPartitions();SelinuxSetupKernelLogging();LOG(INFO) << "Opening SELinux policy";PrepareApexSepolicy();// Read the policy before potentially killing snapuserd.std::string policy;ReadPolicy(&policy);CleanupApexSepolicy();auto snapuserd_helper = SnapuserdSelinuxHelper::CreateIfNeeded();if (snapuserd_helper) {snapuserd_helper->StartTransition();}LoadSelinuxPolicy(policy);if (snapuserd_helper) {// Before enforcing, finish the pending snapuserd transition.snapuserd_helper->FinishTransition();snapuserd_helper = nullptr;}if (selinux_android_restorecon("/dev/selinux/", SELINUX_ANDROID_RESTORECON_RECURSE) == -1) {PLOG(FATAL) << "restorecon failed of /dev/selinux failed";}SelinuxSetEnforcement();if (selinux_android_restorecon("/system/bin/init", 0) == -1) {PLOG(FATAL) << "restorecon failed of /system/bin/init failed";}setenv(kEnvSelinuxStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(), 1);const char* path = "/system/bin/init";const char* args[] = {path, "second_stage", nullptr};execv(path, const_cast<char>(args));//执行second_stagePLOG(FATAL) << "execv(\\"" << path << "\\") failed";return 1;
}
selinux是安全权限相关,感兴趣的大家可以自行学习研究。 在执行完成之后回到init 执行了second_stage。
文件目录:system/core/init/init.cpp 在线地址:
int SecondStageMain(int argc, char** argv) {if (REBOOT_BOOTLOADER_ON_PANIC) {InstallRebootSignalHandlers();}SetStdioToDevNull(argv);InitKernelLogging(argv);LOG(INFO) << "init second stage started!";if (auto result = WriteFile("/proc/1/oom_score_adj", "-1000"); !result) {LOG(ERROR) << "Unable to write -1000 to /proc/1/oom_score_adj: " << result.error();}GlobalSeccomp();keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));property_init();//初始化属性服务process_kernel_dt();process_kernel_cmdline();export_kernel_boot_props();property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));const char* avb_version = getenv("INIT_AVB_VERSION");if (avb_version) property_set("ro.boot.avb_version", avb_version);const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {load_debug_prop = "true"s == force_debuggable_env;}unsetenv("INIT_STARTED_AT");unsetenv("INIT_SELINUX_TOOK");unsetenv("INIT_AVB_VERSION");unsetenv("INIT_FORCE_DEBUGGABLE");SelinuxSetupKernelLogging();SelabelInitialize();SelinuxRestoreContext();//创建EpollEpoll epoll;if (auto result = epoll.Open(); !result) {PLOG(FATAL) << result.error();}//创建Handler,监听子进程的信号,如果子进程异常退出,init会调用对应的处理函数来进行处理。InstallSignalFdHandler(&epoll);property_load_boot_defaults(load_debug_prop);UmountDebugRamdisk();fs_mgr_vendor_overlay_mount_all();export_oem_lock_status();//开启属性服务StartPropertyService(&epoll);MountHandler mount_handler(&epoll);set_usb_controller();const BuiltinFunctionMap function_map;Action::set_function_map(&function_map);if (!SetupMountNamespaces()) {PLOG(FATAL) << "SetupMountNamespaces failed";}subcontexts = InitializeSubcontexts();ActionManager& am = ActionManager::GetInstance();ServiceList& sm = ServiceList::GetInstance();//加载配置脚本文件 init.rcLoadBootScripts(am, sm);if (false) DumpState();// Make the GSI status available before scripts start running.if (android::gsi::IsGsiRunning()) {property_set("ro.gsid.image_running", "1");} else {property_set("ro.gsid.image_running", "0");}am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");am.QueueEventTrigger("early-init");// Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");// ... so that we can start queuing up actions that require stuff from /dev.am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");Keychords keychords;am.QueueBuiltinAction([&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {for (const auto& svc : ServiceList::GetInstance()) {keychords.Register(svc->keycodes());}keychords.Start(&epoll, HandleKeychord);return Success();},"KeychordInit");am.QueueBuiltinAction(console_init_action, "console_init");// Trigger all the boot actions to get us started.am.QueueEventTrigger("init");// Starting the BoringSSL self test, for NIAP certification compliance.am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest");// Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random// wasn't ready immediately after wait_for_coldboot_doneam.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");// Initialize binder before bringing up other system servicesam.QueueBuiltinAction(InitBinder, "InitBinder");// 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.auto epoll_timeout = std::optional<std::chrono::milliseconds>{};if (do_shutdown && !shutting_down) {do_shutdown = false;if (HandlePowerctlMessage(shutdown_command)) {shutting_down = true;}}if (!(waiting_for_prop || Service::is_exec_service_running())) {am.ExecuteOneCommand();}if (!(waiting_for_prop || Service::is_exec_service_running())) {if (!shutting_down) {auto next_process_action_time = HandleProcessActions();// If there's a process that needs restarting, wake up in time for that.if (next_process_action_time) {epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(*next_process_action_time - boot_clock::now());if (*epoll_timeout < 0ms) epoll_timeout = 0ms;}}// If there's more work to do, wake up again immediately.if (am.HasMoreCommands()) epoll_timeout = 0ms;}if (auto result = epoll.Wait(epoll_timeout); !result) {LOG(ERROR) << result.error();}}return 0;
}
代码比较多,我们只需要看关键的几点 我都加了注释: 1.property_init。属性服务类似于Windows平台上的注册表管理器,主要记录一些用户、软件的使用信息。当系统启动、重启 都是根据之前的记录进行对应的初始化。
2.创建Handler,监听子进程的信号,如果子进程异常退出,init会调用对应的处理函数来进行处理。
3.创建Epoll。
4.开启属性服务。
5.解析init.rc配置文件。
顺便提一下,Epoll面试大家遇见的也比较多。后边我会解释Epoll。
下面我们分别看一下 这几个函数都做了什么。
1.属性服务的初始化 ——> property_init
void property_init() {mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH);CreateSerializedPropertyInfo();//创建了配置的infoif (__system_property_area_init()) {//初始化property的内存区域。LOG(FATAL) << "Failed to initialize property area";}if (!property_info_area.LoadDefaultPath()) {LOG(FATAL) << "Failed to load serialized property info file";}
}
总结:创建了Property的info信息。并且初始化了property的内存区域。
2.开启属性服务 -->StartPropertyService
文件目录:/system/core/init/property_service.cpp
void StartPropertyService(Epoll* epoll) {selinux_callback cb;cb.func_audit = SelinuxAuditCallback;//设置selinux的callbackselinux_set_callback(SELINUX_CB_AUDIT, cb);property_set("ro.property_service.version", "2");//创建属性的非阻塞式socketproperty_set_fd = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,false, 0666, 0, 0, nullptr);if (property_set_fd == -1) {PLOG(FATAL) << "start_property_service socket creation failed";}//listen对property_set_fd进行监听,最多可以同时为8个链接提供服务。listen(property_set_fd, 8);//epoll 注册Handler,监听property_set_fd,当有更新的时候会调用handle_property_set_fd来进行处理。if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) {PLOG(FATAL) << result.error();}
}//属性事件处理器
static void handle_property_set_fd() {static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */ //设置超时时长int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC);if (s == -1) {return;}ucred cr;socklen_t cr_size = sizeof(cr);if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {close(s);PLOG(ERROR) << "sys_prop: unable to get SO_PEERCRED";return;}SocketConnection socket(s, cr);uint32_t timeout_ms = kDefaultSocketTimeout;uint32_t cmd = 0;if (!socket.RecvUint32(&cmd, &timeout_ms)) {//接收数据PLOG(ERROR) << "sys_prop: error while reading command from the socket";socket.SendUint32(PROP_ERROR_READ_CMD);return;}switch (cmd) {case PROP_MSG_SETPROP: {//设置属性事件char prop_name[PROP_NAME_MAX];char prop_value[PROP_VALUE_MAX];//从socket中读取name 和 valueif (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||!socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket";return;}prop_name[PROP_NAME_MAX-1] = 0;prop_value[PROP_VALUE_MAX-1] = 0;const auto& cr = socket.cred();std::string error;uint32_t result =HandlePropertySet(prop_name, prop_value, socket.source_context(), cr, &error);//设置属性if (result != PROP_SUCCESS) {LOG(ERROR) << "Unable to set property '" << prop_name << "' to '" << prop_value<< "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": "<< error;}break;}case PROP_MSG_SETPROP2: {//同上std::string name;std::string value;if (!socket.RecvString(&name, &timeout_ms) ||!socket.RecvString(&value, &timeout_ms)) {PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP2): error while reading name/value from the socket";socket.SendUint32(PROP_ERROR_READ_DATA);return;}const auto& cr = socket.cred();std::string error;uint32_t result = HandlePropertySet(name, value, socket.source_context(), cr, &error);if (result != PROP_SUCCESS) {LOG(ERROR) << "Unable to set property '" << name << "' to '" << value<< "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": "<< error;}socket.SendUint32(result);break;}default:LOG(ERROR) << "sys_prop: invalid command " << cmd;socket.SendUint32(PROP_ERROR_INVALID_CMD);break;}
}//设置属性
uint32_t HandlePropertySet(const std::string& name, const std::string& value,const std::string& source_context, const ucred& cr, std::string* error) {if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {return ret;}if (StartsWith(name, "ctl.")) {//控制属性的处理HandleControlMessage(name.c_str() + 4, value, cr.pid);return PROP_SUCCESS;}// sys.powerctl is a special property that is used to make the device reboot. We want to log// any process that sets this property to be able to accurately blame the cause of a shutdown.if (name == "sys.powerctl") {//记录重启设备原因的属性std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);std::string process_cmdline;std::string process_log_string;if (ReadFileToString(cmdline_path, &process_cmdline)) {// Since cmdline is null deliminated, .c_str() conveniently gives us just the process// path.process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());}LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid<< process_log_string;}if (name == "selinux.restorecon_recursive") {return PropertySetAsync(name, value, RestoreconRecursiveAsync, error);}//设置普通属性return PropertySet(name, value, error);
}
我们只看普通属性,因为控制属性需要客户端的权限。static uint32_t PropertySet(const std::string& name, const std::string& value, std::string* error) {size_t valuelen = value.size();if (!IsLegalPropertyName(name)) {*error = "Illegal property name";return PROP_ERROR_INVALID_NAME;}if (valuelen >= PROP_VALUE_MAX && !StartsWith(name, "ro.")) {*error = "Property value too long";return PROP_ERROR_INVALID_VALUE;}if (mbstowcs(nullptr, value.data(), 0) == static_cast<std::size_t>(-1)) {*error = "Value is not a UTF8 encoded string";return PROP_ERROR_INVALID_VALUE;}//从属性内存空间查找,属性存在就更新属性值,否则创建并且添加进去。prop_info* pi = (prop_info*) __system_property_find(name.c_str());if (pi != nullptr) {// ro.* properties are actually "write-once".if (StartsWith(name, "ro.")) {*error = "Read-only property was already set";return PROP_ERROR_READ_ONLY_PROPERTY;}__system_property_update(pi, value.c_str(), valuelen);} else {int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);if (rc < 0) {*error = "__system_property_add failed";return PROP_ERROR_SET_FAILED;}}if (persistent_properties_loaded && StartsWith(name, "persist.")) {WritePersistentProperty(name, value);}property_changed(name, value);return PROP_SUCCESS;
}
总结:创建Android的注册表,将一些用户、应用的信息存储下来 系统会根据这些属性进行初始化工作。创建了property的socket 并且将socket注册到Epoll中,在handle_property_set_fd中将属性添加到内存空间中去。
3.加载init.rc配置文件 --> LoadBootScripts
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {Parser parser = CreateParser(action_manager, service_list);//创建解析器std::string bootscript = GetProperty("ro.boot.init_rc", "");//根据ro.boot.init_rc的属性值来获取需要执行的脚本if (bootscript.empty()) {parser.ParseConfig("/init.rc");if (!parser.ParseConfig("/system/etc/init")) {late_import_paths.emplace_back("/system/etc/init");}if (!parser.ParseConfig("/product/etc/init")) {late_import_paths.emplace_back("/product/etc/init");}if (!parser.ParseConfig("/product_services/etc/init")) {late_import_paths.emplace_back("/product_services/etc/init");}if (!parser.ParseConfig("/odm/etc/init")) {late_import_paths.emplace_back("/odm/etc/init");}if (!parser.ParseConfig("/vendor/etc/init")) {late_import_paths.emplace_back("/vendor/etc/init");}} else {parser.ParseConfig(bootscript);}
}//1.根据action on 和import类型的不同创建不同的解析器
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {Parser parser;parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt));parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));return parser;
}/*2.读取init.rc文件 在init.rc中根据系统导入对应的zygote.rc 在init进程中创建Zygote进程,该进程的可执行文件在/system/bin/app_process 并且传入参数 -Xzygote /system/bin --zygote --start-system-server 指定classname=main */service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-serverclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote stream 660 root systemsocket usap_pool_primary stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdonrestart restart wificondwritepid /dev/cpuset/foreground/tasks3.解析器根据文件的格式来执行对应的动作。
文件目录:system/core/init/service.cpp
在线地址:https://cs.android.com/android/platform/superproject/+/android10-release:system/core/init/service.cpp//开始解析
Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,const std::string& filename, int line) {if (args.size() < 3) {//判断可执行参数 我们传递的参数大于3个的 所以不会到这里来。return Error() << "services must have a name and a program";}const std::string& name = args[1];if (!IsValidName(name)) {//校验Namereturn Error() << "invalid service name '" << name << "'";}filename_ = filename;Subcontext* restart_action_subcontext = nullptr;if (subcontexts_) {for (auto& subcontext : *subcontexts_) {if (StartsWith(filename, subcontext.path_prefix())) {restart_action_subcontext = &subcontext;break;}}}std::vector<std::string> str_args(args.begin() + 2, args.end());if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) {if (str_args[0] == "/sbin/watchdogd") {str_args[0] = "/system/bin/watchdogd";}}//创建service对象service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);return Success();
}//解析完成
Result<Success> ServiceParser::EndSection() {if (service_) {//如果service存在就将原来的service删除 再添加新的Service* old_service = service_list_->FindService(service_->name());if (old_service) {if (!service_->is_override()) {return Error() << "ignored duplicate definition of service '" << service_->name()<< "'";}if (StartsWith(filename_, "/apex/") && !old_service->is_updatable()) {return Error() << "cannot update a non-updatable service '" << service_->name()<< "' with a config in APEX";}service_list_->RemoveService(*old_service);old_service = nullptr;}//调用service_list->addService函数进行添加service_list_->AddService(std::move(service_));}return Success();
}解析完成后需要启动 在init.rc中我们找到对应的启动 之前说到的class = main 而class_start是一个command
on nonencryptedclass_start mainclass_start late_start文件目录: /android/system/core/init static Result<Success> do_class_start(const BuiltinArguments& args) {// Do not start a class if it has a property persist.dont_start_class.CLASS set to 1.if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))return Success();// Starting a class does not start services which are explicitly disabled.// They must be started individually.for (const auto& service : ServiceList::GetInstance()) {//遍历serviceList if (service->classnames().count(args[1])) {if (auto result = service->StartIfNotDisabled(); !result) {//执行startIfNotDisable函数LOG(ERROR) << "Could not start service '" << service->name()<< "' as part of class '" << args[1] << "': " << result.error();}}}return Success();
}文件目录:/system/core/init/service.cpp
Result<Success> Service::StartIfNotDisabled() {if (!(flags_ & SVC_DISABLED)) { //判断有没有在init.rc中配置disabledreturn Start();//开启Zygote} else {flags_ |= SVC_DISABLED_START;}return Success();
}//调用start 开启zygote服务
Result<Success> Service::Start() {if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {ServiceList::GetInstance().DelayService(*this);return Error() << "Cannot start an updatable service '" << name_<< "' before configs from APEXes are all loaded. "<< "Queued for execution.";}bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));if (flags_ & SVC_RUNNING) {//如果服务已经开启 就return Successif ((flags_ & SVC_ONESHOT) && disabled) {flags_ |= SVC_RESTART;}// It is not an error to try to start a service that is already running.return Success();}bool needs_console = (flags_ & SVC_CONSOLE);if (needs_console) {if (console_.empty()) {console_ = default_console;}int console_fd = open(console_.c_str(), O_RDWR | O_CLOEXEC);if (console_fd < 0) {flags_ |= SVC_DISABLED;return ErrnoError() << "Couldn't open console '" << console_ << "'";}close(console_fd);}struct stat sb;//判断对应的执行文件是否存在也就算zygote.rc中的/system/bin/app_process。手机中的/system/bin/app_process文件。if (stat(args_[0].c_str(), &sb) == -1) {flags_ |= SVC_DISABLED;return ErrnoError() << "Cannot find '" << args_[0] << "'";}std::string scon;if (!seclabel_.empty()) {scon = seclabel_;} else {auto result = ComputeContextFromExecutable(args_[0]);if (!result) {return result.error();}scon = *result;}if (!IsRuntimeApexReady() && !pre_apexd_) {pre_apexd_ = true;}post_data_ = ServiceList::GetInstance().IsPostData();LOG(INFO) << "starting service '" << name_ << "'...";//判断进程是否启动,没有启动就fork子进程。所以zygote是init的子进程。pid_t pid = -1;if (namespace_flags_) {pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);} else {pid = fork();}if (pid == 0) {//子进程(zygote)中执行的函数umask(077);if (auto result = EnterNamespaces(); !result) {LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();}if (namespace_flags_ & CLONE_NEWNS) {if (auto result = SetUpMountNamespace(); !result) {LOG(FATAL) << "Service '" << name_<< "' could not set up mount namespace: " << result.error();}}if (namespace_flags_ & CLONE_NEWPID) {if (auto result = SetUpPidNamespace(); !result) {LOG(FATAL) << "Service '" << name_<< "' could not set up PID namespace: " << result.error();}}for (const auto& [key, value] : environment_vars_) {setenv(key.c_str(), value.c_str(), 1);}std::for_each(descriptors_.begin(), descriptors_.end(),std::bind(&DescriptorInfo::CreateAndPublish, std::placeholders::_1, scon));std::string cpuset_path;if (CgroupGetControllerPath("cpuset", &cpuset_path)) {auto cpuset_predicate = [&cpuset_path](const std::string& path) {return StartsWith(path, cpuset_path + "/");};auto iter =std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);if (iter == writepid_files_.end()) {std::string default_cpuset = GetProperty("ro.cpuset.default", "");if (!default_cpuset.empty()) {if (default_cpuset.front() != '/') {default_cpuset.insert(0, 1, '/');}if (default_cpuset.back() != '/') {default_cpuset.push_back('/');}writepid_files_.push_back(StringPrintf("%s%stasks", cpuset_path.c_str(), default_cpuset.c_str()));}}} else {LOG(ERROR) << "cpuset cgroup controller is not mounted!";}std::string pid_str = std::to_string(getpid());for (const auto& file : writepid_files_) {if (!WriteStringToFile(pid_str, file)) {PLOG(ERROR) << "couldn't write " << pid_str << " to " << file;}}if (ioprio_class_ != IoSchedClass_NONE) {if (android_set_ioprio(getpid(), ioprio_class_, ioprio_pri_)) {PLOG(ERROR) << "failed to set pid " << getpid()<< " ioprio=" << ioprio_class_ << "," << ioprio_pri_;}}if (needs_console) {setsid();OpenConsole();} else {ZapStdio();}SetProcessAttributes();//调用execv函数,启动service子进程if (!ExpandArgsAndExecv(args_, sigstop_)) {PLOG(ERROR) << "cannot execve('" << args_[0] << "')";}_exit(127);}if (pid < 0) {pid_ = 0;return ErrnoError() << "Failed to fork";}if (oom_score_adjust_ != -1000) {std::string oom_str = std::to_string(oom_score_adjust_);std::string oom_file = StringPrintf("/proc/%d/oom_score_adj", pid);if (!WriteStringToFile(oom_str, oom_file)) {PLOG(ERROR) << "couldn't write oom_score_adj";}}time_started_ = boot_clock::now();pid_ = pid;flags_ |= SVC_RUNNING;start_order_ = next_start_order_++;process_cgroup_empty_ = false;bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 ||limit_percent_ != -1 || !limit_property_.empty();errno = -createProcessGroup(uid_, pid_, use_memcg);if (errno != 0) {PLOG(ERROR) << "createProcessGroup(" << uid_ << ", " << pid_ << ") failed for service '"<< name_ << "'";} else if (use_memcg) {if (swappiness_ != -1) {if (!setProcessGroupSwappiness(uid_, pid_, swappiness_)) {PLOG(ERROR) << "setProcessGroupSwappiness failed";}}if (soft_limit_in_bytes_ != -1) {if (!setProcessGroupSoftLimit(uid_, pid_, soft_limit_in_bytes_)) {PLOG(ERROR) << "setProcessGroupSoftLimit failed";}}size_t computed_limit_in_bytes = limit_in_bytes_;if (limit_percent_ != -1) {long page_size = sysconf(_SC_PAGESIZE);long num_pages = sysconf(_SC_PHYS_PAGES);if (page_size > 0 && num_pages > 0) {size_t max_mem = SIZE_MAX;if (size_t(num_pages) < SIZE_MAX / size_t(page_size)) {max_mem = size_t(num_pages) * size_t(page_size);}computed_limit_in_bytes =std::min(computed_limit_in_bytes, max_mem / 100 * limit_percent_);}}if (!limit_property_.empty()) {computed_limit_in_bytes = android::base::GetUintProperty(limit_property_, computed_limit_in_bytes, SIZE_MAX);}if (computed_limit_in_bytes != size_t(-1)) {if (!setProcessGroupLimit(uid_, pid_, computed_limit_in_bytes)) {PLOG(ERROR) << "setProcessGroupLimit failed";}}}NotifyStateChange("running");return Success();
}static bool ExpandArgsAndExecv(const std::vector<std::string>& args, bool sigstop) {std::vector<std::string> expanded_args;std::vector<char*> c_strings;expanded_args.resize(args.size());c_strings.push_back(const_cast<char*>(args[0].data()));for (std::size_t i = 1; i < args.size(); ++i) {if (!expand_props(args[i], &expanded_args[i])) {LOG(FATAL) << args[0] << ": cannot expand '" << args[i] << "'";}c_strings.push_back(expanded_args[i].data());}c_strings.push_back(nullptr);if (sigstop) {kill(getpid(), SIGSTOP);}//执行app_process 也就是调用app_main.cpp的main函数 这样就进入到zygote了。return execv(c_strings[0], c_strings.data()) == 0;
}
init.rc是一个配置文件,主要包含了5中类型语句:Action、Command、Service、Option和Import。具体的语法大家可以参考ReadMe 里面写的非常详细。
总结:加载并解析init.rc 根据rc文件创建Service对象,最终将service添加到service_List中,然后解析到on 执行 class_start的时候会开启服务调用Service::Start函数,fork子进程,并且执行app_process文件 开启了zygote,也就到了zygote的main函数中了。 zygote的main函数如下:
int main(int argc, char* const argv[])
{if (!LOG_NDEBUG) {String8 argv_String;for (int i = 0; i < argc; ++i) {argv_String.append("\\"");argv_String.append(argv[i]);argv_String.append("\\" ");}ALOGV("app_process main with argv: %s", argv_String.string());}AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));argc--;argv++;const char* spaced_commands[] = { "-cp", "-classpath" };// Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).bool known_command = false;int i;for (i = 0; i < argc; i++) {if (known_command == true) {runtime.addOption(strdup(argv[i]));ALOGV("app_process main add known option '%s'", argv[i]);known_command = false;continue;}for (int j = 0;j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));++j) {if (strcmp(argv[i], spaced_commands[j]) == 0) {known_command = true;ALOGV("app_process main found known command '%s'", argv[i]);}}if (argv[i][0] != '-') {break;}if (argv[i][1] == '-' && argv[i][2] == 0) {++i; // Skip --.break;}runtime.addOption(strdup(argv[i]));ALOGV("app_process main add option '%s'", argv[i]);}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;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) {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;}}Vector<String8> args;if (!className.isEmpty()) {args.add(application ? String8("application") : String8("tool"));runtime.setClassNameAndArgs(className, argc - i, argv + i);if (!LOG_NDEBUG) {String8 restOfArgs;char* const* argv_new = argv + i;int argc_new = argc - i;for (int k = 0; k < argc_new; ++k) {restOfArgs.append("\\"");restOfArgs.append(argv_new[k]);restOfArgs.append("\\" ");}ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());}} else {maybeCreateDalvikCache();if (startSystemServer) {args.add(String8("start-system-server"));}char prop[PROP_VALUE_MAX];if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",ABI_LIST_PROPERTY);return 11;}String8 abiFlag("--abi-list=");abiFlag.append(prop);args.add(abiFlag);for (; i < argc; ++i) {args.add(String8(argv[i]));}}if (!niceName.isEmpty()) {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.");}
}
这样init的就唤起了Zygote了。
Zygote
1.Zygote的启动
在之前的init中有讲到,init解析init.rc的时候会解析service字段 并添加到serviceList中,并且执行fork对应的进程,执行程序。这些启动脚本都存放在 system/core/rootdir
目录中。
代码如下:
#解析服务 并且添加到serviceList中
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-serverclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote stream 660 root systemsocket usap_pool_primary stream 660 root systemonrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart audioserveronrestart restart cameraserveronrestart restart mediaonrestart restart netdonrestart restart wificondwritepid /dev/cpuset/foreground/tasks#遍历serviceList 调用start函数 fork进程 execv执行app_process64
on nonencrypted class_start main class_start late_start
app_process64对应代码就在/frameworks/base/cmds/app_process
目录下。对应的源文件就是app_main.cpp。 init进程启动后通过调用execv(“/system/bin/app_process64”,“-Xzygote /system/bin --zygote --start-system-server”) 执行程序,并且将参数传递给main函数。
接下来我们看看zygote的main函数做了什么?
//init传递过来的参数如下 -Xzygote /system/bin --zygote --start-system-server
int main(int argc, char* const argv[])
{//#ifndef LOG_NDEBUG//#ifdef NDEBUG//#define LOG_NDEBUG 1//#else//#define LOG_NDEBUG 0 所以这里是true 会把参数存放到argv_String中,然后打印出来if (!LOG_NDEBUG) {String8 argv_String;for (int i = 0; i < argc; ++i) {argv_String.append(""");argv_String.append(argv[i]);argv_String.append("" ");}ALOGV("app_process main with argv: %s", argv_String.string());}//创建开启AppRuntime,并将参数传递给AppRuntimeAppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));argc--;argv++;bool known_command = false;int i;for (i = 0; i < argc; i++) {if (known_command == true) {runtime.addOption(strdup(argv[i]));ALOGV("app_process main add known option '%s'", argv[i]);known_command = false;continue;}for (int j = 0;j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));++j) {if (strcmp(argv[i], spaced_commands[j]) == 0) {known_command = true;ALOGV("app_process main found known command '%s'", argv[i]);}}if (argv[i][0] != '-') {//如果参数第一个字符是'-'跳出循环,Zygote传递的第一个参数是-Xzygote 所以执行到这里会跳出循环break;}if (argv[i][1] == '-' && argv[i][2] == 0) {++i; // Skip --.break;}runtime.addOption(strdup(argv[i]));ALOGV("app_process main add option '%s'", argv[i]);}// Parse runtime arguments. Stop at first unrecognized option.bool zygote = false;bool startSystemServer = false;bool application = false;String8 niceName;String8 className;++i; while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {//传递的参数有--zygote的就把zygote赋值为true niceName = zygotezygote = true;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) { //传递的参数有start--system-server 把startSystemServer 赋值为tue表示当前进程的main是需要开启system_server的startSystemServer = true;} else if (strcmp(arg, "--application") == 0) {//如果传递的参数包含了--application 表示当前是应用程序application = true;} else if (strncmp(arg, "--nice-name=", 12) == 0) {//指定进程名niceName.setTo(arg + 12);} else if (strncmp(arg, "--", 2) != 0) {//application程序传递过来的className 也就是需要启动的classclassName.setTo(arg);break;} else {--i;break;}}Vector<String8> args;if (!className.isEmpty()) {//如果class不为空 说明是application,但是此时我们是空的,所以我们会走下面的分支args.add(application ? String8("application") : String8("tool"));runtime.setClassNameAndArgs(className, argc - i, argv + i);if (!LOG_NDEBUG) {String8 restOfArgs;char* const* argv_new = argv + i;int argc_new = argc - i;for (int k = 0; k < argc_new; ++k) {restOfArgs.append(""");restOfArgs.append(argv_new[k]);restOfArgs.append("" ");}ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());}} else {//这里就是zygote启动模式// We're in zygote mode.maybeCreateDalvikCache();//创建Dalvik的缓存目录, data/dalvik-cache的目录if (startSystemServer) {//如果需要运行system_server的 会添加这个参数args.add(String8("start-system-server"));}char prop[PROP_VALUE_MAX];if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",ABI_LIST_PROPERTY);return 11;}String8 abiFlag("--abi-list=");abiFlag.append(prop);args.add(abiFlag);for (; i < argc; ++i) {args.add(String8(argv[i]));}}if (!niceName.isEmpty()) {//设置进程别名runtime.setArgv0(niceName.string(), true /* setProcName */);}if (zygote) {//注意这里之前传递的参数zygote 所以这里是true。他会调用runtime的start函数 传递com.android.internal.os.ZygoteInit 以及 init传递过来的参数 和trueruntime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {//application模式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.");}
}
代码比较长,我总结下首先会打印日志把传递过来的参数打印出来。接着会创建AppRuntime
对象,将参数传递给AppRuntime并初始化。接着根据init传递过来的参数--zygote
把zygote
设置成true
表示是以zygote模式启动,如果需要开启system_server的会把start-system-server
也设置为true
。如果传递的是application就是以app模式启动,他就会查找对应的className,如果className部位空就会添加对应的参数。否则就是Zygote模式,在Zygote模式中会先创建Davik的缓存目录。最后调用runtime.start()
,看是以什么模式启动,如果是Zygote模式启动就会传递com.android.internal.os.ZygoteInit
和将整理的参数以及zygote 传递下去,如果是app模式就会传递com.android.internal.os.RuntimeInit
和 args以及 zygote;
2.AndroidRuntime
接下来我们需要接触两个非常重要的类AppRuntime和AndroidRuntime。这两个类是整个Android Runtime环境的接口类, 他们的关系是:
class AppRuntime : public AndroidRuntime
AppRuntime是AndroidRuntime的子类。
看看AppRuntime::start()
我们看到AppRuntime没有start函数,start函数的实现在父类AndroidRuntime
中。我们直接跳到AndroidRuntime中看看。 文件目录:/framework/base/core/jni/AndroidRuntime
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{ALOGD(">>>>>> START %s uid %d <<<<<<\\n",className != NULL ? className : "(unknown)", getuid());static const String8 startSystemServer("start-system-server");/ 'startSystemServer == true' means runtime is obsolete and not run from* init.rc anymore, so we print out the boot start event here.*/for (size_t i = 0; i < options.size(); ++i) {if (options[i] == startSystemServer) {/* track our progress through the boot sequence */const int LOG_BOOT_PROGRESS_START = 3000;LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));}}//获取ANDROID_ROOT 目录const char* rootDir = getenv("ANDROID_ROOT");if (rootDir == NULL) {rootDir = "/system";if (!hasDir("/system")) {LOG_FATAL("No root directory specified, and /system does not exist.");return;}setenv("ANDROID_ROOT", rootDir, 1);}//获取ANDROID_RUNTIME_ROOT目录const char* runtimeRootDir = getenv("ANDROID_RUNTIME_ROOT");if (runtimeRootDir == NULL) {LOG_FATAL("No runtime directory specified with ANDROID_RUNTIME_ROOT environment variable.");return;}const char* tzdataRootDir = getenv("ANDROID_TZDATA_ROOT");if (tzdataRootDir == NULL) {LOG_FATAL("No tz data directory specified with ANDROID_TZDATA_ROOT environment variable.");return;}/* start the virtual machine */JniInvocation jni_invocation;jni_invocation.Init(NULL);//初始化JNI,加载libart.soJNIEnv* env;if (startVm(&mJavaVM, &env, zygote) != 0) {//创建虚拟机return;}onVmCreated(env);//当VM创建成功后会把env传递给AppRuntime来进行处理。if (startReg(env) < 0) {//开启注册函数 会注册很多关键的JNI函数 比如com/android/internal/os/ZygoteInit.nativeZygoteInit->com_android_internal_os_ZygoteInit_nativeZygoteInit等等函数的注册ALOGE("Unable to register all android natives\\n");return;}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);//创建对应的class 此时的className 就是main函数传递过来的com.android.internal.os.ZygoteInit 把他存入strArrayclassNameStr = 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);}char* slashClassName = toSlashClassName(className != NULL ? className : "");//把className的. 替换成/jclass startClass = env->FindClass(slashClassName);if (startClass == NULL) {ALOGE("JavaVM unable to locate class '%s'\\n", slashClassName);/* keep going */} else {//执行ZygoteInit的main方法 带着传递过来的参数 回调到java层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 {env->CallStaticVoidMethod(startClass, startMeth, strArray);#if 0if (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");
}
首先校验一些目录,然后加载libart.so,创建VM虚拟机,创建成功之后会调用onVmCreated(env)
回到AppRuntime中,不过我们当前是Zygote 直接 return。函数如下
virtual void onVmCreated(JNIEnv* env)
{if (mClassName.isEmpty()) {return; // Zygote. Nothing to do here.}char* slashClassName = toSlashClassName(mClassName.string());mClass = env->FindClass(slashClassName);if (mClass == NULL) {ALOGE("ERROR: could not find class '%s'\\n", mClassName.string());}free(slashClassName);mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
}
下来调用startReg(env);开启注册函数,在这里会注册非常多的JNI函数,例如com/android/internal/os/ZygoteInit.nativeZygoteInit->com_android_internal_os_ZygoteInit_nativeZygoteInit
等等。 接着调用toSlashClassName()把main函数传递过来的com.android.internal.os.ZygoteInit
,把.
替换成/
。通过env->findClass(“com/android/internal/os/ZygoteInit”)查找到对应的javaClass,再调用对应的Main函数。这样Zygote就进入了Java层。
我们看下Java层的代码: 文件目录:/frameworks/base/core/java/com/android/internal/os/ZygoteInit
public static void main(String argv[]) {//zygoteServer服务端ZygoteServer zygoteServer = null;ZygoteHooks.startZygoteNoThreadCreation();try {Os.setpgid(0, 0);} catch (ErrnoException ex) {throw new RuntimeException("Failed to setpgid(0,0)", ex);}Runnable caller;try {// Report Zygote start time to tron unless it is a runtime restartif (!"1".equals(SystemProperties.get("sys.boot_completed"))) {MetricsLogger.histogram(null, "boot_zygote_init",(int) SystemClock.elapsedRealtime());}String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,Trace.TRACE_TAG_DALVIK);bootTimingsTraceLog.traceBegin("ZygoteInit");RuntimeInit.enableDdms();boolean startSystemServer = false;String zygoteSocketName = "zygote";String abiList = null;boolean enableLazyPreload = false;for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {//此时我们传递的是有值的 所以会把startSystemServer 设置为truestartSystemServer = 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)) {zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());} else {throw new RuntimeException("Unknown command line argument: " + argv[i]);}}final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);if (abiList == null) {throw new RuntimeException("No ABI list supplied.");}if (!enableLazyPreload) {bootTimingsTraceLog.traceBegin("ZygotePreload");EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());//预加载资源preload(bootTimingsTraceLog);EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());bootTimingsTraceLog.traceEnd(); // ZygotePreload} else {Zygote.resetNicePriority();}bootTimingsTraceLog.traceBegin("PostZygoteInitGC");gcAndFinalize();//GC的初始化并启动bootTimingsTraceLog.traceEnd(); // PostZygoteInitGCbootTimingsTraceLog.traceEnd(); // ZygoteInit// Disable tracing so that forked processes do not inherit stale tracing tags from// Zygote.Trace.setTracingEnabled(false, 0);Zygote.initNativeState(isPrimaryZygote);ZygoteHooks.stopZygoteNoThreadCreation();zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {//此时为True 调用forkSystemServerRunnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);// {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.if (r != null) {r.run();return;}}Log.i(TAG, "Accepting command socket connections");// The select loop returns early in the child process after a fork and// loops forever in the zygote.//服务端开启循环 等待客户端来请求caller = zygoteServer.runSelectLoop(abiList);} catch (Throwable ex) {Log.e(TAG, "System zygote died with exception", ex);throw ex;} finally {if (zygoteServer != null) {zygoteServer.closeServerSocket();}}// We're in the child process and have exited the select loop. Proceed to execute the// command.if (caller != null) {caller.run();}
}
在ZygoteInit的Main函数中,首先创建了ZygoteServer服务端用于和客户端通信,因为Zygote是C/S架构的嘛。我们从init中带过来的参数start-system-server
所以当前的startSystemServer
是True。接着调用了preload()
static void preload(TimingsTraceLog bootTimingsTraceLog) {Log.d(TAG, "begin preload");bootTimingsTraceLog.traceBegin("BeginPreload");beginPreload();bootTimingsTraceLog.traceEnd(); // BeginPreloadbootTimingsTraceLog.traceBegin("PreloadClasses");preloadClasses();//预加载class 比如我们用到的activity fragment service等等 文件目录在/framework/base/config/preloaded-classesbootTimingsTraceLog.traceEnd(); // PreloadClassesbootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");cacheNonBootClasspathClassLoaders();bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoadersbootTimingsTraceLog.traceBegin("PreloadResources");preloadResources();//预加载系统资源 比如主题 图片等等bootTimingsTraceLog.traceEnd(); // PreloadResourcesTrace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");nativePreloadAppProcessHALs();//HAL 硬件抽象层Trace.traceEnd(Trace.TRACE_TAG_DALVIK);Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");maybePreloadGraphicsDriver();Trace.traceEnd(Trace.TRACE_TAG_DALVIK);preloadSharedLibraries();//预加载库资源preloadTextResources();// Ask the WebViewFactory to do any initialization that must run in the zygote process,// for memory sharing purposes.//WebView相关WebViewFactory.prepareWebViewInZygote();endPreload();warmUpJcaProviders();Log.d(TAG, "end preload");sPreloadComplete = true;
}//预加载class
private static void preloadClasses() {final VMRuntime runtime = VMRuntime.getRuntime();InputStream is;try {is = new FileInputStream(PRELOADED_CLASSES);} catch (FileNotFoundException e) {Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");return;}Log.i(TAG, "Preloading classes...");long startTime = SystemClock.uptimeMillis();// Drop root perms while running static initializers.final int reuid = Os.getuid();final int regid = Os.getgid();boolean droppedPriviliges = false;if (reuid == ROOT_UID && regid == ROOT_GID) {try {Os.setregid(ROOT_GID, UNPRIVILEGED_GID);Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);} catch (ErrnoException ex) {throw new RuntimeException("Failed to drop root", ex);}droppedPriviliges = true;}float defaultUtilization = runtime.getTargetHeapUtilization();runtime.setTargetHeapUtilization(0.8f);try {BufferedReader br =new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);//创建BufferReader读取文件int count = 0;String line;while ((line = br.readLine()) != null) {// Skip comments and blank lines.line = line.trim();if (line.startsWith("#") || line.equals("")) {continue;}Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);try {if (false) {Log.v(TAG, "Preloading " + line + "...");}//通过Class.forName来预加载ClassClass.forName(line, true, null);count++;} catch (ClassNotFoundException e) {Log.w(TAG, "Class not found for preloading: " + line);} catch (UnsatisfiedLinkError e) {Log.w(TAG, "Problem preloading " + line + ": " + e);} catch (Throwable t) {Log.e(TAG, "Error preloading " + line + ".", t);if (t instanceof Error) {throw (Error) t;}if (t instanceof RuntimeException) {throw (RuntimeException) t;}throw new RuntimeException(t);}Trace.traceEnd(Trace.TRACE_TAG_DALVIK);}Log.i(TAG, "...preloaded " + count + " classes in "+ (SystemClock.uptimeMillis() - startTime) + "ms.");} catch (IOException e) {Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);} finally {IoUtils.closeQuietly(is);// Restore default.runtime.setTargetHeapUtilization(defaultUtilization);// Fill in dex caches with classes, fields, and methods brought in by preloading.Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");runtime.preloadDexCaches();Trace.traceEnd(Trace.TRACE_TAG_DALVIK);// Bring back root. We'll need it later if we're in the zygote.if (droppedPriviliges) {try {Os.setreuid(ROOT_UID, ROOT_UID);Os.setregid(ROOT_GID, ROOT_GID);} catch (ErrnoException ex) {throw new RuntimeException("Failed to restore root", ex);}}}
}
在preload函数中,预加载了很多的资源比如class(我们常用的Activity Fragment android.app.ActivityManager…),也加载了一些系统资源 比如图片 颜色 主题等等。大家知道为什么要在这里加载这些资源吗? 之前有说过fork 会和父进程共享内存,写数据的时候会复制。所有的应用都是由于Zygote孵化,所以在这里进行预加载 所孵化的应用也默认拥有这些资源。
接着startSystemServer
为 True
所以会执行forkSystemServer,关于SystemServer我们留在下次讲。最后执行zygoteServer.runSelectLoop();
Runnable runSelectLoop(String abiList) {ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();socketFDs.add(mZygoteSocket.getFileDescriptor());peers.add(null);while (true) {fetchUsapPoolPolicyPropsWithMinInterval();int[] usapPipeFDs = null;StructPollfd[] pollFDs = null;//需要监听的fdsif (mUsapPoolEnabled) {usapPipeFDs = Zygote.getUsapPipeFDs();pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];} else {pollFDs = new StructPollfd[socketFDs.size()];}int pollIndex = 0;for (FileDescriptor socketFD : socketFDs) {pollFDs[pollIndex] = new StructPollfd();pollFDs[pollIndex].fd = socketFD;pollFDs[pollIndex].events = (short) POLLIN;//对每一个socket需要关注POLLIN++pollIndex;}final int usapPoolEventFDIndex = pollIndex;if (mUsapPoolEnabled) {pollFDs[pollIndex] = new StructPollfd();pollFDs[pollIndex].fd = mUsapPoolEventFD;pollFDs[pollIndex].events = (short) POLLIN;++pollIndex;for (int usapPipeFD : usapPipeFDs) {FileDescriptor managedFd = new FileDescriptor();managedFd.setInt$(usapPipeFD);pollFDs[pollIndex] = new StructPollfd();pollFDs[pollIndex].fd = managedFd;pollFDs[pollIndex].events = (short) POLLIN;++pollIndex;}}try {//zygote阻塞在这里等待poll事件Os.poll(pollFDs, -1);} catch (ErrnoException ex) {throw new RuntimeException("poll failed", ex);}boolean usapPoolFDRead = false;//注意这里是采用的倒序方式的,也就是说优先处理已经建立连接的请求,后处理新建立链接的请求while (--pollIndex >= 0) {if ((pollFDs[pollIndex].revents & POLLIN) == 0) {continue;}if (pollIndex == 0) {//初始化的时候socketFDs中只有server socket。所以会创建新的通信连接调用acceptCommandPeer// Zygote server socketZygoteConnection newPeer = acceptCommandPeer(abiList);peers.add(newPeer);socketFDs.add(newPeer.getFileDescriptor());} else if (pollIndex < usapPoolEventFDIndex) {// Session socket accepted from the Zygote server sockettry {//获取到客户端链接ZygoteConnection connection = peers.get(pollIndex);//客户端有请求进行处理final Runnable command = connection.processOneCommand(this);if (mIsForkChild) {if (command == null) {throw new IllegalStateException("command == null");}return command;} else {if (command != null) {throw new IllegalStateException("command != null");}// We don't know whether the remote side of the socket was closed or// not until we attempt to read from it from processOneCommand. This// shows up as a regular POLLIN event in our regular processing loop.if (connection.isClosedByPeer()) {connection.closeSocket();peers.remove(pollIndex);socketFDs.remove(pollIndex);}}} catch (Exception e) {if (!mIsForkChild) {Slog.e(TAG, "Exception executing zygote command: ", e);ZygoteConnection conn = peers.remove(pollIndex);conn.closeSocket();socketFDs.remove(pollIndex);} else {Log.e(TAG, "Caught post-fork exception in child process.", e);throw e;}} finally {mIsForkChild = false;}} else {long messagePayload = -1;try {byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {DataInputStream inputStream =new DataInputStream(new ByteArrayInputStream(buffer));messagePayload = inputStream.readLong();} else {Log.e(TAG, "Incomplete read from USAP management FD of size "+ readBytes);continue;}} catch (Exception ex) {if (pollIndex == usapPoolEventFDIndex) {Log.e(TAG, "Failed to read from USAP pool event FD: "+ ex.getMessage());} else {Log.e(TAG, "Failed to read from USAP reporting pipe: "+ ex.getMessage());}continue;}if (pollIndex > usapPoolEventFDIndex) {Zygote.removeUsapTableEntry((int) messagePayload);}usapPoolFDRead = true;}}if (usapPoolFDRead) {int[] sessionSocketRawFDs =socketFDs.subList(1, socketFDs.size()).stream().mapToInt(fd -> fd.getInt$()).toArray();final Runnable command = fillUsapPool(sessionSocketRawFDs);if (command != null) {return command;}}}
}
首先注册poll的event 对POLLIN敏感,Os.poll(pollFDs),通过acceptCommandPeer
创建Socket服务端的连接对象ZygoteConnection,通过 processOneCommand
处理客户端的请求。
Runnable processOneCommand(ZygoteServer zygoteServer) {String args[];ZygoteArguments parsedArgs = null;FileDescriptor[] descriptors;try {args = Zygote.readArgumentList(mSocketReader);descriptors = mSocket.getAncillaryFileDescriptors();} catch (IOException ex) {throw new IllegalStateException("IOException on command socket", ex);}if (args == null) {isEof = true;return null;}int pid = -1;FileDescriptor childPipeFd = null;FileDescriptor serverPipeFd = null;parsedArgs = new ZygoteArguments(args);if (parsedArgs.mAbiListQuery) {handleAbiListQuery();return null;}if (parsedArgs.mPidQuery) {handlePidQuery();return null;}if (parsedArgs.mUsapPoolStatusSpecified) {return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled);}if (parsedArgs.mPreloadDefault) {handlePreload();return null;}if (parsedArgs.mPreloadPackage != null) {handlePreloadPackage(parsedArgs.mPreloadPackage, parsedArgs.mPreloadPackageLibs,parsedArgs.mPreloadPackageLibFileName, parsedArgs.mPreloadPackageCacheKey);return null;}if (canPreloadApp() && parsedArgs.mPreloadApp != null) {byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp);Parcel appInfoParcel = Parcel.obtain();appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length);appInfoParcel.setDataPosition(0);ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(appInfoParcel);appInfoParcel.recycle();if (appInfo != null) {handlePreloadApp(appInfo);} else {throw new IllegalArgumentException("Failed to deserialize --preload-app");}return null;}if (parsedArgs.mApiBlacklistExemptions != null) {return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions);}if (parsedArgs.mHiddenApiAccessLogSampleRate != -1|| parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) {return handleHiddenApiAccessLogSampleRate(zygoteServer,parsedArgs.mHiddenApiAccessLogSampleRate,parsedArgs.mHiddenApiAccessStatslogSampleRate);}if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) {throw new ZygoteSecurityException("Client may not specify capabilities: "+ "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities)+ ", effective=0x" + Long.toHexString(parsedArgs.mEffectiveCapabilities));}Zygote.applyUidSecurityPolicy(parsedArgs, peer);Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer);Zygote.applyDebuggerSystemProperty(parsedArgs);Zygote.applyInvokeWithSystemProperty(parsedArgs);int[][] rlimits = null;if (parsedArgs.mRLimits != null) {rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);}int[] fdsToIgnore = null;if (parsedArgs.mInvokeWith != null) {try {FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);childPipeFd = pipeFds[1];serverPipeFd = pipeFds[0];Os.fcntlInt(childPipeFd, F_SETFD, 0);fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};} catch (ErrnoException errnoEx) {throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);}}int [] fdsToClose = { -1, -1 };FileDescriptor fd = mSocket.getFileDescriptor();if (fd != null) {fdsToClose[0] = fd.getInt$();}fd = zygoteServer.getZygoteSocketFileDescriptor();if (fd != null) {fdsToClose[1] = fd.getInt$();}fd = null;//调用native的forkpid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);try {if (pid == 0) {// 在子进程中 首先关闭掉ServerSocket,因为它是Zygote孵化出来的 所以socket 需要关闭掉。zygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;//调用HandleChildProc mStartChildZygote = --start-child-zygotereturn handleChildProc(parsedArgs, descriptors, childPipeFd,parsedArgs.mStartChildZygote);} 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);}}
processOneCommand客户端请求的处理函数:通过Zygote.forkAndSpecialize
调用到native函数nativeForkAndSpecialize
来fork出来客户端进程。
文件目录:/frameworks/base/core/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,jint runtime_flags, jobjectArray rlimits,jint mount_external, jstring se_info, jstring nice_name,jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,jstring instruction_set, jstring app_data_dir) {……………………pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);if (pid == 0) {SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,capabilities, capabilities,mount_external, se_info, nice_name, false,is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);}return pid;
}static pid_t ForkCommon(JNIEnv* env, bool is_system_server,const std::vector<int>& fds_to_close,const std::vector<int>& fds_to_ignore) {SetSignalHandlers();……………………pid_t pid = fork();//fork出来客户端请求的进程。if (pid == 0) {// The child process.PreApplicationInit();// Clean up any descriptors which must be closed immediatelyDetachDescriptors(env, fds_to_close, fail_fn);// Invalidate the entries in the USAP table.ClearUsapTable();// Re-open all remaining open file descriptors so that they aren't shared// with the zygote across a fork.gOpenFdTable->ReopenOrDetach(fail_fn);// Turn fdsan back on.android_fdsan_set_error_level(fdsan_error_level);} else {ALOGD("Forked child process %d", pid);}
fork出来进程之后在子进程中 首先关闭掉ServerSocket,因为它是Zygote孵化出来的 所以socket 需要关闭掉。 调用handleParentProc
设置子进程.
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd, boolean isZygote) {closeSocket();//关闭socketif (descriptors != null) {try {Os.dup2(descriptors[0], STDIN_FILENO);Os.dup2(descriptors[1], STDOUT_FILENO);Os.dup2(descriptors[2], STDERR_FILENO);for (FileDescriptor fd: descriptors) {IoUtils.closeQuietly(fd);}} catch (ErrnoException ex) {Log.e(TAG, "Error reopening stdio", ex);}}if (parsedArgs.mNiceName != null) {Process.setArgV0(parsedArgs.mNiceName);}// End of the postFork event.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);if (parsedArgs.mInvokeWith != null) {WrapperInit.execApplication(parsedArgs.mInvokeWith,parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,VMRuntime.getCurrentInstructionSet(),pipeFd, parsedArgs.mRemainingArgs);// Should not get here.throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");} else {if (!isZygote) {//此时看客户端是否传递--start-child-zygotereturn ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);} else {return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mRemainingArgs, null /* classLoader */);}}
}
关闭当前socket,然后根据客户端传递的参数来决定是走哪一个逻辑,如果不是child-zygote就会执行ZygoteInit.zygoteInit();
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();//调用了nativeZygoteInitZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
调用了native函数nativeZygoteInit 在AndroidRuntime中
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{gCurRuntime->onZygoteInit();
}
调用到AppRuntime的onZygoteInit
virtual void onZygoteInit()
{//这个可以看我之前写的binder文章。让当前进程支持IPC通讯,binder。sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\\n");proc->startThreadPool();
}
最后调用RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader)
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {nativeSetExitWithoutCleanup(true);VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);final Arguments args = new Arguments(argv);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);//根据客户端请求args 来找到需要启动的class 执行Main函数return findStaticMain(args.startClass, args.startArgs, classLoader);
}protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {Class<?> cl;try {cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className,ex);}Method m;try {m = cl.getMethod("main", new Class[] { String[].class });} catch (NoSuchMethodException ex) {throw new RuntimeException("Missing static main on " + className, ex);} catch (SecurityException ex) {throw new RuntimeException("Problem getting static main on " + className, ex);}int modifiers = m.getModifiers();if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {throw new RuntimeException("Main method is not public and static on " + className);}return new MethodAndArgsCaller(m, argv);
}
最后返回MethodAndArgsCaller到ZygoteInit.java的Main函数中 执行对应的run 函数.也就是客户端请求的class的Main函数了。
static class MethodAndArgsCaller implements Runnable {/ method to call */private final Method mMethod;/ argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {try {mMethod.invoke(null, new Object[] { mArgs });} catch (IllegalAccessException ex) {throw new RuntimeException(ex);} catch (InvocationTargetException ex) {Throwable cause = ex.getCause();if (cause instanceof RuntimeException) {throw (RuntimeException) cause;} else if (cause instanceof Error) {throw (Error) cause;}throw new RuntimeException(ex);}}
}
以上整个Zygote的流程就结束了。