Android系统的启动
先看启动相关进程的关系图
[TOC]
相关的文件
- init.cpp
- app_main.cpp
- ZygoteInit.java
- SystemServer.java
init进程
init.main
1 | int main(int argc, char** argv) { |
根据上面的源码,来分析init进程干了些啥?
- 提供属性服务(包括初始化服务和启动属性服务);
- 解析init.rc文件;
- 根据init.rc文件生成设备驱动节点;
- 提供无限循环来处理事件,同时提供了子进程的终止方式;
我们说Zygote进程由init进程创建,那么init进程是在什么时候启动Zygote进程的呢?
上面说到init进程会解析init.rc文件,在init.rc文件的头部,它引入了Zygote相关的.rc文件
1 | import /init.environ.rc |
这里Zygote相关的文件有:
- init.zygote64_32.rc
- init.zygote32_64.rc
- init.zygote64.rc
个人猜测存在三个版本可能是为了32位机器与64位机器间的转换。
init.zygote64.rc文件内容如下:
1 | service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server |
当init进程解析到上面的内容时便会进行zygote进程的创建。
init进程会根据是否是oneshot来决定在Zygote进程退出后是否会重新创建(oneshot为true则不重新创建,为false则重新创建,默认为false,所以Zygote进程一旦被杀死会立即有init进程重新创建出来)
Zygote进程
Zygote进程启动后会执行到frameworks/base/cmds/app_process/app_main.cpp文件的main()方法. 整个调用流程如下:
1 | app_main.main |
app_main.main方法部分代码如下:
1 | int main(int argc, char* const argv[]) |
如果zygote为true,就执行ZygoteInit的main方法,否则执行RuntimeInit的main方法
AndroidRuntime的start()
方法中先后分别调用了startVm()
(创建Java虚拟机)和startReg()
(JNI 方法注册),最后调用env->CallStaticVoidMethod(startClass, startMeth, strArray);
通过反射来找到ZygoteInit.java的main方法并执行,并因此从C和C++世界进入到了了Java世界。
ZygoteInit.main方法干了什么呢?
1 | public static void main(String argv[]) { |
ZygoteInit.startSystemServer()
1 | /** |
小结
Zygote 进程完成了JVM的创建、JNI方法的注册,并作为Java进程的鼻祖,用于孵化Java进程,再创建完system_server进程后,调用runSelectLoop(),随时待命,当接收到创建新进程请求时立即唤醒并重新工作。
system_server
在Zygote进程条用startSystemServer()
孵化出system_server
进程后,会调用handleSystemServerProcess()
方法,该方法如下:
1 | /** |
根据上面的代码,可以看出:
如果system_server已经存在,会有一个argument合并的过程,合并之后交由ART(Android Runtime)处理;
system_server 完成了PathClassLoader类加载器的创建;
会调用RuntimeInit.zygoteInit方法;
RuntimeInit.zygoteInit
1 | public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { |
这个方法的调用完成了两件事情:
完成了进程binder线程池的启动,
nativeZygoteInit()
最终会走到app_main.cpp的onZygoteInit()
方法,该方法如下:1
2
3
4
5
6virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool(); // 启动Binder线程池
}捕获特殊异常,
applicationInit
方法最终会抛出ZygoteInit.MethodAndArgsCaller(m, argv)
异常,代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
...
// 设置目标对利用率
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
// 设置tagetSDKVersion
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// 找到目标类的静态main方法并调用,同时抛出异常
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
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);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}MethodAndArgsCaller相关说明:
- 该异常实现了Runnable接口;
- 该异常有ZygoteInit.main方法捕获;
- 该异常捕获后,其run方法会被调用,调用后会执行SystemServer的main方法;
SystemServer
SystemServer的main方法主要就是先创建SystemServer对象,然后调用其run方法。run方法干了啥?
- SystemProperties的设置;
- VMRuntime的设置;
- 准备主线程的Looper;
- android_servers.so库的加载;
- System Context的初始化;
- SystemServiceManager的创建;
- 各种服务的开启:
startBootstrapServices();
startCoreServices();
startOtherServices();
- 调用Looper.loop()开启循环;
SystemServer启动服务分几个不同的阶段,分别是:
1 | /* |
- start,调用start方法,会先开启几个关键的服务,如AMS、PowerManagerService、LightService、DisplayManagerService;
- phase100(即
PHASE_WAIT_FOR_DEFAULT_DISPLAY
):创建PKMS, WMS, IMS, DBMS, LockSettingsService, JobSchedulerService, MmsService等服务; - phase480 && 500(即
PHASE_LOCK_SETTINGS_READY
和PHASE_ACTIVITY_MANAGER_READY
): 进入Phase480, 调用WMS, PMS, PKMS, DisplayManagerService这4个服务的systemReady(); - phase550: 进入phase550, 执行AMS.systemReady(), 启动SystemUI, WebViewFactory, Watchdog.
- Phase600: 进入phase600, 执行AMS.systemReady(), 执行各种服务的systemRunning().
- Phase1000: 进入1000, 执行finishBooting, 启动启动on-hold进程.
SystemServer的主线程在经过上面几个步骤后,主线程启动总算完毕,在Looper.loop()
后开始等待其他线程通过Handler发送消息再处理
普通app进程
普通app的进程和system_server进程启动的流程类似,只是最后调用的main方法不同,普通app进程最后调用的是ActivityThread.main
方法,而system_server调用的是SystemServer.main
总结
这里对系统启动时的一些进程做个总结性描述。
核心进程及其对应的main方法
进程名 | 对应的main方法 |
---|---|
init进程 | init.main() |
zygote进程 | ZygoteInit.main() |
app_process进程 | RuntimeInit.main() |
SystemServer进程 | SystemServer.main() |
app进程 | ActivityThread.main() |
注意app_process进程是指通过/system/bin/app_process启动的进程,且后面跟的参数不带–zygote,即并非启动zygote进程。 比如常见的有通过adb shell方式来执行am,pm等命令,便是这种方式。
进程重启导致的关联性
重启的进程 | 关联重启的进程 |
---|---|
zygote | 触发media、netd以及zygote的子进程(system_server)重启 |
system_server | 触发zygote重启 |
surfaceflinger | 触发zygote重启 |
servicemanager | 触发zygote、healthd、media、surfaceflinger、drm重启 |