系统进程启动流程分析(一)
Android啟動(dòng)概覽
眾所周知,Android是谷歌開(kāi)發(fā)的一款基于Linux的開(kāi)源操作系統(tǒng),下圖所示為 Android 平臺(tái)的主要組件
1. Linux 內(nèi)核
Android 平臺(tái)的基礎(chǔ)是 Linux 內(nèi)核。例如,Android Runtime (ART) 依靠 Linux 內(nèi)核來(lái)執(zhí)行底層功
能,例如線(xiàn)程和低層內(nèi)存管理。
使用 Linux 內(nèi)核可讓 Android 利用主要安全功能,并且允許設(shè)備制造商為著名的內(nèi)核開(kāi)發(fā)硬件驅(qū)動(dòng)程
序。
2. 硬件抽象層 (HAL)
硬件抽象層 (HAL) 提供標(biāo)準(zhǔn)界面,向更高級(jí)別的 Java API 框架顯示設(shè)備硬件功能。HAL 包含多個(gè)
庫(kù)模塊,其中每個(gè)模塊都為特定類(lèi)型的硬件組件實(shí)現(xiàn)一個(gè)界面,例如相機(jī)或藍(lán)牙模塊。當(dāng)框架 API
要求訪(fǎng)問(wèn)設(shè)備硬件時(shí),Android 系統(tǒng)將為該硬件組件加載庫(kù)模塊。
3. Android Runtime
對(duì)于運(yùn)行 Android 5.0(API 級(jí)別 21)或更高版本的設(shè)備,每個(gè)應(yīng)用都在其自己的進(jìn)程中運(yùn)行,并
且有其自己的 Android Runtime (ART) 實(shí)例。ART 編寫(xiě)為通過(guò)執(zhí)行 DEX 文件在低內(nèi)存設(shè)備上運(yùn)行
多個(gè)虛擬機(jī),DEX 文件是一種專(zhuān)為 Android 設(shè)計(jì)的字節(jié)碼格式,經(jīng)過(guò)優(yōu)化,使用的內(nèi)存很少。編
譯工具鏈(例如 Jack)將 Java 源代碼編譯為 DEX 字節(jié)碼,使其可在 Android 平臺(tái)上運(yùn)行。
ART 的部分主要功能包括:
預(yù)先 (AOT) 和即時(shí) (JIT) 編譯
優(yōu)化的垃圾回收 (GC)
在 Android 9(API 級(jí)別 28)及更高版本的系統(tǒng)中,支持將應(yīng)用軟件包中的 Dalvik Executable 格
式 (DEX) 文件轉(zhuǎn)換為更緊湊的機(jī)器代碼。
更好的調(diào)試支持,包括專(zhuān)用采樣分析器、詳細(xì)的診斷異常和崩潰報(bào)告,并且能夠設(shè)置觀察點(diǎn)以監(jiān)控
特定字段
在 Android 版本 5.0(API 級(jí)別 21)之前,Dalvik 是 Android Runtime。如果您的應(yīng)用在 ART 上
運(yùn)行效果很好,那么它應(yīng)該也可在 Dalvik 上運(yùn)行,但反過(guò)來(lái)不一定。
Android 還包含一套核心運(yùn)行時(shí)庫(kù),可提供 Java API 框架所使用的 Java 編程語(yǔ)言中的大部分功能,包括
一些 Java 8 語(yǔ)言功能。
4. 原生 C/C++ 庫(kù)
許多核心 Android 系統(tǒng)組件和服務(wù)(例如 ART 和 HAL)構(gòu)建自原生代碼,需要以 C 和 C++ 編寫(xiě)的
原生庫(kù)。Android 平臺(tái)提供 Java 框架 API 以向應(yīng)用顯示其中部分原生庫(kù)的功能。例如,您可以通
過(guò) Android 框架的 Java OpenGL API 訪(fǎng)問(wèn) OpenGL ES,以支持在應(yīng)用中繪制和操作 2D 和 3D 圖形。
如果開(kāi)發(fā)的是需要 C 或 C++ 代碼的應(yīng)用,可以使用 Android NDK 直接從原生代碼訪(fǎng)問(wèn)某些原生平臺(tái)庫(kù)。
5. Java API 框架
您可通過(guò)以 Java 語(yǔ)言編寫(xiě)的 API 使用 Android OS 的整個(gè)功能集。這些 API 形成創(chuàng)建 Android 應(yīng)
用所需的構(gòu)建塊,它們可簡(jiǎn)化核心模塊化系統(tǒng)組件和服務(wù)的重復(fù)使用,包括以下組件和服務(wù):
豐富、可擴(kuò)展的視圖系統(tǒng),可用以構(gòu)建應(yīng)用的 UI,包括列表、網(wǎng)格、文本框、按鈕甚至可嵌入的網(wǎng)
絡(luò)瀏覽器
資源管理器,用于訪(fǎng)問(wèn)非代碼資源,例如本地化的字符串、圖形和布局文件
通知管理器,可讓所有應(yīng)用在狀態(tài)欄中顯示自定義提醒
Activity 管理器,用于管理應(yīng)用的生命周期,提供常見(jiàn)的導(dǎo)航返回棧
內(nèi)容提供程序,可讓?xiě)?yīng)用訪(fǎng)問(wèn)其他應(yīng)用(例如“聯(lián)系人”應(yīng)用)中的數(shù)據(jù)或者共享其自己的數(shù)據(jù)
開(kāi)發(fā)者可以完全訪(fǎng)問(wèn) Android 系統(tǒng)應(yīng)用使用的框架 API。
6. 系統(tǒng)應(yīng)用
Android 隨附一套用于電子郵件、短信、日歷、互聯(lián)網(wǎng)瀏覽和聯(lián)系人等的核心應(yīng)用。平臺(tái)隨附的應(yīng)
用與用戶(hù)可以選擇安裝的應(yīng)用一樣,沒(méi)有特殊狀態(tài)。因此第三方應(yīng)用可成為用戶(hù)的默認(rèn)網(wǎng)絡(luò)瀏覽
器、短信 Messenger 甚至默認(rèn)鍵盤(pán)(有一些例外,例如系統(tǒng)的“設(shè)置”應(yīng)用)。
系統(tǒng)應(yīng)用可用作用戶(hù)的應(yīng)用,以及提供開(kāi)發(fā)者可從其自己的應(yīng)用訪(fǎng)問(wèn)的主要功能。例如,如果您的應(yīng)用
要發(fā)短信,您無(wú)需自己構(gòu)建該功能,可以改為調(diào)用已安裝的短信應(yīng)用向您指定的接收者發(fā)送消息。
接下來(lái),我們來(lái)看下Android系統(tǒng)啟動(dòng)的大概流程,如下圖所示:
第一步: 啟動(dòng)電源以及系統(tǒng)啟動(dòng)
當(dāng)電源按下,引導(dǎo)芯片代碼開(kāi)始從預(yù)定義的地方(固化在ROM)開(kāi)始執(zhí)行。加載引導(dǎo)程序到RAM,然后
執(zhí)行
第二步:引導(dǎo)程序
引導(dǎo)程序是在Android操作系統(tǒng)開(kāi)始運(yùn)行前的一個(gè)小程序。引導(dǎo)程序是運(yùn)行的第一個(gè)程序,因此它是針
對(duì)特定的主板與芯片的。設(shè)備制造商要么使用很受歡迎的引導(dǎo)程序比如redboot、uboot、qi
bootloader或者開(kāi)發(fā)自己的引導(dǎo)程序,它不是Android操作系統(tǒng)的一部分。引導(dǎo)程序是OEM廠(chǎng)商或者運(yùn)
營(yíng)商加鎖和限制的地方。
引導(dǎo)程序分兩個(gè)階段執(zhí)行。
第一個(gè)階段,檢測(cè)外部的RAM以及加載對(duì)第二階段有用的程序;
第二階段,引導(dǎo)程序設(shè)置網(wǎng)絡(luò)、內(nèi)存等等。這些對(duì)于運(yùn)行內(nèi)核是必要的,為了達(dá)到特殊的目標(biāo),引導(dǎo)程
序可以根據(jù)配置參數(shù)或者輸入數(shù)據(jù)設(shè)置內(nèi)核。
Android引導(dǎo)程序可以在\bootable\bootloader\legacy\usbloader找到。傳統(tǒng)的加載器包含兩個(gè)文件,
需要在這里說(shuō)明:
init.s初始化堆棧,清零BBS段,調(diào)用main.c的_main()函數(shù);
main.c初始化硬件(鬧鐘、主板、鍵盤(pán)、控制臺(tái)),創(chuàng)建linux標(biāo)簽
第三步:內(nèi)核
Android內(nèi)核與桌面linux內(nèi)核啟動(dòng)的方式差不多。內(nèi)核啟動(dòng)時(shí),設(shè)置緩存、被保護(hù)存儲(chǔ)器、計(jì)劃列表,
加載驅(qū)動(dòng)。當(dāng)內(nèi)核完成系統(tǒng)設(shè)置,它首先在系統(tǒng)文件中尋找”init”文件,然后啟動(dòng)root進(jìn)程或者系統(tǒng)的第
一個(gè)進(jìn)程
第四步:init進(jìn)程
init進(jìn)程是Linux系統(tǒng)中用戶(hù)空間的第一個(gè)進(jìn)程,進(jìn)程號(hào)固定為1。Kernel啟動(dòng)后,在用戶(hù)空間啟動(dòng)init進(jìn)
程,并調(diào)用init中的main()方法執(zhí)行init進(jìn)程的職責(zé)。
第五步:啟動(dòng)Lancher App
init進(jìn)程分析
其中init進(jìn)程是Android系統(tǒng)中及其重要的第一個(gè)進(jìn)程,接下來(lái)我們來(lái)看下init進(jìn)程注意做了些什么
1. 創(chuàng)建和掛載啟動(dòng)所需要的文件目錄
2. 初始化和啟動(dòng)屬性服務(wù)
3. 解析init.rc配置文件并啟動(dòng)Zygote進(jìn)程
init.rc解析
init.rc是一個(gè)非常重要的配置文件,它是由Android初始化語(yǔ)言(Android Init Language)編寫(xiě)的腳
本,它主要包含五種類(lèi)型語(yǔ)句:Action(Action中包含了一系列的Command)、Commands(init語(yǔ)言
中的命令)、Services(由init進(jìn)程啟動(dòng)的服務(wù))、Options(對(duì)服務(wù)進(jìn)行配置的選項(xiàng))和Import(引入
其他配置文件)。init.rc的配置代碼如下所示。
Action
Action: 通過(guò)觸發(fā)器trigger,即以on開(kāi)頭的語(yǔ)句來(lái)決定執(zhí)行相應(yīng)的service的時(shí)機(jī),具體有如下時(shí)機(jī):
- on early-init; 在初始化早期階段觸發(fā);
- on init; 在初始化階段觸發(fā);
- on late-init; 在初始化晚期階段觸發(fā);
- on boot/charger: 當(dāng)系統(tǒng)啟動(dòng)/充電時(shí)觸發(fā),還包含其他情況,此處不一一列舉;
- on property:=: 當(dāng)屬性值滿(mǎn)足條件時(shí)觸發(fā)
Service
服務(wù)Service,以 service開(kāi)頭,由init進(jìn)程啟動(dòng),一般運(yùn)行在init的一個(gè)子進(jìn)程,所以啟動(dòng)service前需要
判斷對(duì)應(yīng)的可執(zhí)行文件是否存在。init生成的子進(jìn)程,定義在rc文件,其中每一個(gè)service在啟動(dòng)時(shí)會(huì)通過(guò)
fork方式生成子進(jìn)程。
例如: ?service servicemanager /system/bin/servicemanager 代表的是服務(wù)名為
servicemanager,服務(wù)執(zhí)行的路徑為/system/bin/servicemanager。
Command
下面列舉常用的命令
- class_start <service_class_name>: 啟動(dòng)屬于同一個(gè)class的所有服務(wù);
- start <service_name>: 啟動(dòng)指定的服務(wù),若已啟動(dòng)則跳過(guò);
- stop <service_name>: 停止正在運(yùn)行的服務(wù)
- setprop :設(shè)置屬性值
- mkdir :創(chuàng)建指定目錄
- symlink <sym_link>: 創(chuàng)建連接到的<sym_link>符號(hào)鏈接;
- write : 向文件path中寫(xiě)入字符串;
- exec: fork并執(zhí)行,會(huì)阻塞init進(jìn)程直到程序完畢;
- exprot :設(shè)定環(huán)境變量;
- loglevel :設(shè)置log級(jí)別
Options
Options是Service的可選項(xiàng),與service配合使用
- disabled: 不隨class自動(dòng)啟動(dòng),只有根據(jù)service名才啟動(dòng);
- oneshot: service退出后不再重啟;
- user/group: 設(shè)置執(zhí)行服務(wù)的用戶(hù)/用戶(hù)組,默認(rèn)都是root;
- class:設(shè)置所屬的類(lèi)名,當(dāng)所屬類(lèi)啟動(dòng)/退出時(shí),服務(wù)也啟動(dòng)/停止,默認(rèn)為default;
- onrestart:當(dāng)服務(wù)重啟時(shí)執(zhí)行相應(yīng)命令;
- socket: 創(chuàng)建名為 /dev/socket/<name> 的socket
- critical: 在規(guī)定時(shí)間內(nèi)該service不斷重啟,則系統(tǒng)會(huì)重啟并進(jìn)入恢復(fù)模式
default: 意味著disabled=false,oneshot=false,critical=false。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote -- start-system-serverclass mainpriority -20user rootgroup root readproc reserved_disksocket zygote 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/tasksservice解析流程
// \system\core\init\init.cpp LoadBootScripts() L110 static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {Parser parser = CreateParser(action_manager, service_list);//創(chuàng)建解析器std::string bootscript = GetProperty("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("/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);//開(kāi)始解析} // \system\core\init\init.cpp CreateParser() L100 Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {Parser parser;parser.AddSectionParser("service", std::make_unique<ServiceParser> (&service_list, subcontexts));//service解析parser.AddSectionParser("on", std::make_unique<ActionParser> (&action_manager, subcontexts));parser.AddSectionParser("import", std::make_unique<ImportParser> (&parser));return parser; } // \system\core\init\parser.cpp ParseData() L 42 void Parser::ParseData(const std::string& filename, const std::string& data, size_t* parse_errors) {...for (;;) {switch (next_token(&state)) {case T_EOF:end_section();return;case T_NEWLINE:...if (section_parsers_.count(args[0])) {end_section();section_parser = section_parsers_[args[0]].get();section_start_line = state.line;if (auto result =section_parser->ParseSection(std::move(args), filename, state.line);// L95!result) {(*parse_errors)++;LOG(ERROR) << filename << ": " << state.line << ": " << result.error();section_parser = nullptr;}} else if (section_parser) {if (auto result = section_parser- >ParseLineSection(std::move(args), state.line);// L102!result) {(*parse_errors)++;LOG(ERROR) << filename << ": " << state.line << ": " << result.error();}}args.clear();break;case T_TEXT:args.emplace_back(state.text);break;}} } // \system\core\init\service.cpp ParseSection() L1180 Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,const std::string& filename, int line) {if (args.size() < 3) {return Error() << "services must have a name and a program";}const std::string& name = args[1];if (!IsValidName(name)) {return Error() << "invalid service name '" << name << "'";}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());service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);//構(gòu)建出一個(gè)service對(duì)象return Success(); } // \system\core\init\service.cpp ParseLineSection() L1206 Result<Success> ServiceParser::ParseLineSection(std::vector<std::string>&& args, int line) {return service_ ? service_->ParseLine(std::move(args)) : Success(); } // \system\core\init\service.cpp EndSection() L1210 Result<Success> ServiceParser::EndSection() {if (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()<< "'";}service_list_->RemoveService(*old_service);old_service = nullptr;}service_list_->AddService(std::move(service_)); }return Success(); } // \system\core\init\service.cpp AddService() L1082 void ServiceList::AddService(std::unique_ptr<Service> service) {services_.emplace_back(std::move(service)); } 上面解析完成后,接下來(lái)就是啟動(dòng)Service,這里我們以啟動(dòng)Zygote來(lái)分析 # \system\core\rootdir\init.rc L680 on nonencryptedclass_start main //class_start是一個(gè)命令,通過(guò)do_class_start函數(shù)處理class_start late_start // \system\core\init\builtins..cpp do_class_start() L101 static Result<Success> do_class_start(const BuiltinArguments& args) {// Starting a class does not start services which are explicitly disabled.// They must be started individually.for (const auto& service : ServiceList::GetInstance()) {if (service->classnames().count(args[1])) {if (auto result = service->StartIfNotDisabled(); !result) {LOG(ERROR) << "Could not start service '" << service->name()<< "' as part of class '" << args[1] << "': " << result.error();}}}return Success(); } // \system\core\init\service.cpp StartIfNotDisabled() L977 Result<Success> Service::StartIfNotDisabled() {if (!(flags_ & SVC_DISABLED)) {return Start();} else {flags_ |= SVC_DISABLED_START;}return Success(); } // \system\core\init\service.cpp Start() L785 Result<Success> Service::Start() {//如果service已經(jīng)運(yùn)行,則不啟動(dòng)if (flags_ & SVC_RUNNING) {if ((flags_ & SVC_ONESHOT) && disabled) {flags_ |= SVC_RESTART;}// It is not an error to try to start a service that is already running.return Success(); }...//判斷需要啟動(dòng)的service的對(duì)應(yīng)的執(zhí)行文件是否存在,不存在則不啟動(dòng)servicestruct stat sb;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;}LOG(INFO) << "starting service '" << name_ << "'...";//如果子進(jìn)程沒(méi)有啟動(dòng),則調(diào)用fork函數(shù)創(chuàng)建子進(jìn)程pid_t pid = -1;if (namespace_flags_) {pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);} else {pid = fork();}if (pid == 0) {//當(dāng)期代碼邏輯在子進(jìn)程中運(yùn)行umask(077);//調(diào)用execv函數(shù),啟動(dòng)sevice子進(jìn)程if (!ExpandArgsAndExecv(args_)) {PLOG(ERROR) << "cannot execve('" << args_[0] << "')";}_exit(127);}return Success(); }Zygote概敘
Zygote中文翻譯為“受精卵”,正如其名,它主要用于孵化子進(jìn)程。在Android系統(tǒng)中有以下兩種程序:
java應(yīng)用程序,主要基于ART虛擬機(jī),所有的應(yīng)用程序apk都屬于這類(lèi)native程序,也就是利用C或C++語(yǔ)
言開(kāi)發(fā)的程序,如bootanimation。所有的Java應(yīng)用程序進(jìn)程及系統(tǒng)服務(wù)SystemServer進(jìn)程都由Zygote
進(jìn)程通過(guò)Linux的fork()函數(shù)孵化出來(lái)的,這也就是為什么把它稱(chēng)為Zygote的原因,因?yàn)樗拖褚粋€(gè)受精
卵,孵化出無(wú)數(shù)子進(jìn)程,而native程序則由Init程序創(chuàng)建啟動(dòng)。Zygote進(jìn)程最初的名字不是“zygote”而是
“app_process”,這個(gè)名字是在Android.mk文件中定義的
Zgyote是Android中的第一個(gè)art虛擬機(jī),他通過(guò)socket的方式與其他進(jìn)程進(jìn)行通信。這里的“其他進(jìn)程”
其實(shí)主要是系統(tǒng)進(jìn)程——SystemServer
Zygote是一個(gè)C/S模型,Zygote進(jìn)程作為服務(wù)端,它主要負(fù)責(zé)創(chuàng)建Java虛擬機(jī),加載系統(tǒng)資源,啟
動(dòng)SystemServer進(jìn)程,以及在后續(xù)運(yùn)行過(guò)程中啟動(dòng)普通的應(yīng)用程序,其他進(jìn)程作為客戶(hù)端向它發(fā)
出“孵化”請(qǐng)求,而Zygote接收到這個(gè)請(qǐng)求后就“孵化”出一個(gè)新的進(jìn)程。比如,當(dāng)點(diǎn)擊Launcher里的
應(yīng)用程序圖標(biāo)去啟動(dòng)一個(gè)新的應(yīng)用程序進(jìn)程時(shí),這個(gè)請(qǐng)求會(huì)到達(dá)框架層的核心服務(wù)
ActivityManagerService中,當(dāng)AMS收到這個(gè)請(qǐng)求后,它通過(guò)調(diào)用Process類(lèi)發(fā)出一個(gè)“孵化”子進(jìn)
程的Socket請(qǐng)求,而Zygote監(jiān)聽(tīng)到這個(gè)請(qǐng)求后就立刻fork一個(gè)新的進(jìn)程出來(lái)
Zygote觸發(fā)過(guò)程
1. init.zygoteXX.rc
import /init.${ro.zygote}.rc
${ro.zygote} 會(huì)被替換成 ro.zyogte 的屬性值,這個(gè)是由不同的硬件廠(chǎng)商自己定制的,
有四個(gè)值,
zygote32: zygote 進(jìn)程對(duì)應(yīng)的執(zhí)行程序是 app_process (純 32bit 模式)
zygote64: zygote 進(jìn)程對(duì)應(yīng)的執(zhí)行程序是 app_process64 (純 64bit 模式)
zygote32_64: 啟動(dòng)兩個(gè) zygote 進(jìn)程 (名為 zygote 和 zygote_secondary),對(duì)應(yīng)的執(zhí)行程序分別
是 app_process32 (主模式)
zygote64_32: 啟動(dòng)兩個(gè) zygote 進(jìn)程 (名為 zygote 和 zygote_secondary),對(duì)應(yīng)的執(zhí)行程序分別
是 app_process64 (主模式)、app_process32
2. start zygote
位置:system\core\rootdir\init.rc 560
zygote-start 是在 on late-init 中觸發(fā)的
# Mount filesystems and start core system services. on late-inittrigger early-fs# Mount fstab in init.{$device}.rc by mount_all command. Optional parameter# '--early' can be specified to skip entries with 'latemount'.# /system and /vendor must be mounted by the end of the fs stage,# while /data is optional.trigger fstrigger post-fs# Mount fstab in init.{$device}.rc by mount_all with '--late' parameter# to only mount entries with 'latemount'. This is needed if '--early' is# specified in the previous mount_all command on the fs stage.# With /system mounted and properties form /system + /factory available,# some services can be started.trigger late-fs# Now we can mount /data. File encryption requires keymaster to decrypt# /data, which in turn can only be loaded when system properties are present.trigger post-fs-data# Now we can start zygote for devices with file based encryptiontrigger zygote-start # zygote-start 是在 on late-init 中觸發(fā)的# Load persist properties and override properties (if enabled) from /data.trigger load_persist_props_action# Remove a file to wake up anything waiting for firmware.trigger firmware_mounts_completetrigger early-boottrigger boot if (bootmode == "charger") {am.QueueEventTrigger("charger");} else {am.QueueEventTrigger("late-init");}3. app_processXX
位置\frameworks\base\cmds\app_process\
Zygote啟動(dòng)過(guò)程
位置\frameworks\base\cmds\app_process\app_main.cpp
在app_main.cpp的main函數(shù)中,主要做的事情就是參數(shù)解析. 這個(gè)函數(shù)有兩種啟動(dòng)模式:
1. 一種是zygote模式,也就是初始化zygote進(jìn)程,傳遞的參數(shù)有--start-system-server --socket-
name=zygote,前者表示啟動(dòng)SystemServer,后者指定socket的名稱(chēng)
2. 一種是application模式,也就是啟動(dòng)普通應(yīng)用程序,傳遞的參數(shù)有class名字以及class帶的參數(shù)
兩者最終都是調(diào)用AppRuntime對(duì)象的start函數(shù),加載ZygoteInit或RuntimeInit兩個(gè)Java類(lèi),并將之前
整理的參數(shù)傳入進(jìn)去
app_process
// \frameworks\base\cmds\app_process\app_main.cpp main() L280 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;} // L349 ?? if (zygote) {//這些Java的應(yīng)用都是通過(guò) AppRuntime.start(className)開(kāi)始的//其實(shí)AppRuntime是AndroidRuntime的子類(lèi),它主要實(shí)現(xiàn)了幾個(gè)回調(diào)函數(shù),而start()方 法是實(shí)現(xiàn)在AndroidRuntime這個(gè)方法類(lèi)里runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);}app_process 里面定義了三種應(yīng)用程序類(lèi)型:
1. Zygote: com.android.internal.os.ZygoteInit
2. System Server, 不單獨(dú)啟動(dòng),而是由Zygote啟動(dòng)
3. 其他指定類(lèi)名的Java 程序
?
總結(jié)
以上是生活随笔為你收集整理的系统进程启动流程分析(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何讲解一个C语言程序,解读第一个C++
- 下一篇: 鸿蒙系统体验报告,我雷某人摊牌了,鸿蒙2