一、關(guān)于Android系統(tǒng)重要的進(jìn)程
(1)、init進(jìn)程:init進(jìn)程是Linux內(nèi)核啟動完成之后,啟動的第一個(gè)用戶進(jìn)程,Android系統(tǒng)就是在這個(gè)進(jìn)程的基礎(chǔ)上啟動起來的,進(jìn)程pid為1。init進(jìn)程通過解析init.rc來陸續(xù)啟動其他關(guān)鍵的系統(tǒng)服務(wù)進(jìn)程---其中最重要的是:ServiceManager,Zygote和SystemServer。
(2)、ServiceManager:主要負(fù)責(zé)添加服務(wù),獲取服務(wù),查找服務(wù)以及當(dāng)某個(gè)服務(wù)意外終止時(shí),對該服務(wù)的資源進(jìn)行回收。
(3)、Zygote進(jìn)程:Zygote是一個(gè)孵化器進(jìn)程,所有的應(yīng)用程序進(jìn)程以及系統(tǒng)服務(wù)進(jìn)程SystemServer都是由Zygote進(jìn)程fork出來的。在Zygote中進(jìn)行添加虛擬機(jī)參數(shù),并將其啟動起來,然后注冊JNI函數(shù)。在Zygote中進(jìn)行預(yù)加載以及初始化核心類庫。最后將SystemServer啟動起來。
(4)、SystemServer:啟動系統(tǒng)各項(xiàng)服務(wù)。
二、init.rc腳本語法規(guī)則
service <name> <pathname> [ <argument> ]* //service的名字,啟動路徑,以及參數(shù)
<option>
<option>
...
<name>:
表示此service的名稱
<pathname>:
此service所在的路徑。因?yàn)槭强蓤?zhí)行文件,所以一定有存儲路徑。
<argument>:
啟動service所帶的參數(shù)。
<option>:
對此service的約束選項(xiàng)。
具體請參考:【Android源碼分析】init.rc語法
三、ServiceManager,Zygote,SystemServer的啟動簡析
3.1 ServiceManager
? ? ? ?ServiceManager是Binder機(jī)制中的“DNS服務(wù)器”,負(fù)責(zé)域名(某Binder服務(wù)在ServiceManager注冊時(shí)提供的名稱)IP地址(由底層Binder驅(qū)動分配的值)的解析。
? ? ? ?ServiceManager是在servicemanager.rc(Android8.0)里面描述,并由init進(jìn)程啟動。
/*android-8.0.0_r1\frameworks\native\cmds\servicemanager\servicemanager.rc*/
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
writepid /dev/cpuset/system-background/tasks
? ? ? ?可以看到,Servicemanager是一個(gè)Linux程序。它在設(shè)備中的存儲路徑是:/system/bin/servicemanager
,源碼路徑則是:
android-8.0.0_r1\frameworks\native\cmds\servicemanager\servicemanager.c
? ? ? ?ServiceManager所屬的class
是core
,其他同類的系統(tǒng)進(jìn)程包括ueventd,console(/system/bin/sh),adbd等。根據(jù)core
組的特性,這些進(jìn)程會同時(shí)被啟動或停止
。另外,critical
選項(xiàng)說明它是系統(tǒng)的關(guān)鍵進(jìn)程---意味著如果進(jìn)程不幸在4分鐘內(nèi)異常退出超過4次,則設(shè)備將重啟并進(jìn)入還原模式。當(dāng)ServiceManager每次重啟是,其他關(guān)鍵進(jìn)程如zygote,media,surfaceflinger等也會被restart。
3.2 Zygote
? ? ? ?在Android系統(tǒng)中,所有的應(yīng)用程序進(jìn)程
以及系統(tǒng)服務(wù)進(jìn)程SystemServer
都是由Zygote
進(jìn)程孕育(fork)出來的,因?yàn)锳ndroid系統(tǒng)是基于Linux內(nèi)核的,而在Linux系統(tǒng)中,所有的進(jìn)程都是init進(jìn)程的子孫進(jìn)程,也就是說,所有的進(jìn)程都是直接或者間接地由init進(jìn)程fork出來的。Zygote進(jìn)程也不例外,它是在系統(tǒng)啟動的過程,由init進(jìn)程創(chuàng)建的,在系統(tǒng)啟動腳本android-8.0.0_r1\system\core\rootdir\init.*.rc
文件中,我們可以看到啟動Zygote進(jìn)程的腳本命令:摘自【Android Zygote系統(tǒng)進(jìn)程啟動過程分析(Android N)】
/*android-8.0.0_r1\system\core\rootdir\init.*.rc*/例如:init.zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
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
從上面這段腳本描述可以看出:
ServiceName:zygote
Path:/system/bin/app_process
Arguments:-Xzygote /system/bin --zygote --start-system-server
? ? ? ?Zygote所屬class
為main
,而不是core。和其同class的系統(tǒng)進(jìn)程有netd,debuggerd,rild等。從zygote的path可以看出,它所在的應(yīng)用程序名叫"app_process
"。通過指定--zygote
參數(shù),app_process可以識別出用戶是否需要啟動zygote。
"app_process"程序源碼路徑在:android-8.0.0_r1\frameworks\base\cmds\app_process\app_main.cpp
中。
android-8.0.0_r1\frameworks\base\cmds\app_process\Android.mk主要內(nèi)容:
LOCAL_SRC_FILES:= \
app_main.cpp
LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
LOCAL_SHARED_LIBRARIES := \
libdl \
libcutils \
libutils \
liblog \
libbinder \
libnativeloader \
libandroid_runtime \
$(app_process_common_shared_libs) \
LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
LOCAL_MODULE:= app_process
"app_process"的源碼路徑在:
android-8.0.0_r1\frameworks\base\cmds\app_process\app_main.cpp
其主要函數(shù):
int main(int argc, char* const argv[])
{
...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// After the parent dir, we expect one or more the following internal
// arguments :
//
// --zygote : Start in zygote mode
// --start-system-server : Start the system server.
// --application : Start in application (stand alone, non zygote) mode.
// --nice-name : The nice name for this process.
// 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;
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()) {
// We're not in zygote mode, the only argument we need to pass
// to RuntimeInit is the application argument.
//
// The Remainder of args get passed to startup class main(). Make
// copies of them before we overwrite them with the process name.
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
} else {
// We're in zygote mode.
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);
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string());
set_process_name(niceName.string());
}
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.");
return 10;
}
}
因?yàn)椋诖薸nit.rc指定了--zygote選項(xiàng),因而app_process接下來將啟動"ZygoteInit"并傳入"start-system-server"。
AppRuntime 繼承自AndroidRuntime,所以,runtime.start()函數(shù)對應(yīng)源碼:
android-8.0.0_r1\frameworks\base\core\jni\AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {//啟動虛擬機(jī)
return;
}
onVmCreated(env);//虛擬機(jī)啟動后的回調(diào)
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
}
除了與裝載各種系統(tǒng)類(具體實(shí)現(xiàn)在ZygoteInit#preload()這個(gè)方法里)外,ZygoteInit的另一個(gè)重要工作就是啟動SystemServer---這是大部分Android系統(tǒng)服務(wù)(由Java語言編寫)的所在地。
3.3 SystemServer(Android的系統(tǒng)服務(wù))
? ? ? ?SystemServer是Android進(jìn)入Laucher前的最后準(zhǔn)備。
? ? ? ?一旦在init.rc中為zygote指定了啟動參數(shù)--start-system-server,那么ZygoteInit就會調(diào)用startSystemServer來啟動SystemServer。
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
...
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
...
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();
handleSystemServerProcess(parsedArgs);
}
return true;
}
? ? ? ?根據(jù)fork的特性,子進(jìn)程和父進(jìn)程將獲得同樣的代碼環(huán)境。當(dāng)變量pid值為0時(shí),說明是子進(jìn)程,否則是父進(jìn)程;
如果是前者的話,則進(jìn)一步調(diào)用handleSystemServerProcess來完成剩下的工作,也是最核心的部分---啟動各種系統(tǒng)服務(wù)。并在一切準(zhǔn)備就緒后進(jìn)入Launcher主界面。
說明:本篇博客,主要為源碼分析、學(xué)習(xí)筆記總結(jié),部分內(nèi)容摘自《深入理解Android內(nèi)核設(shè)計(jì)思想》。