了解SystemServer之前,我们知道
- Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中。—上帝init.rc
- 系统启动时init进程会创建Zygote进程(准确的说是通过app_main.cpp启动的Zygote进程),Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。—android大boss,孵化进程
- Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如AMS,PMS等。—android大boss首席小弟
- 下面查看一波源码,源码版本是2.3.7。
本文分析流程图
1>system/core/rootdir/init.rc
而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的,他会去打开一个叫做app_process的文件夹下面的目录。
文件目录:
可以看到文件目录下有mk文件和一个cpp文件。
mk文件:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
app_main.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libandroid_runtime
LOCAL_MODULE:= app_process
include $(BUILD_EXECUTABLE)
总体来说,就是去加载app_main.cpp这个文件。
2>frameworks/base/cmds/app_process.rc
核心代码:
bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false;
......
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
这里的runtime实际上是AppRuntime类型,而这个AppRuntime类型在底层是继承了AndroidRuntime.cpp,它调用的start方法实际上就是AndroidRuntime.cpp中的start方法(俩参数的重载)。
AndroidRuntime.cpp#start(const char* className, const bool startSystemServer)
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*/
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
className != NULL ? className : "(unknown)");
char* slashClassName = NULL;
char* cp;
JNIEnv* env;
blockSigpipe();
/*
* 'startSystemServer == true' means runtime is obslete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
if (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)));
}
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir(