Android设备的启动必须经历3个阶段,即Boot Loader,Linux Kernel和Android系统服务。严格来讲Android系统实际上是运行于Linux 内核上的一系列用户进程,并不算一个严格意义上的操作系统。一般面试问及启动流程都是从init进程开始
重要的系统进程
第一个系统进程--init
init进程的pid值为0.通过解析init.rc脚本来构建出系统的初始运行形态,Android系统的native服务程序大多是在对应的rc脚本中描述并被相继启动。列举下几个由init进程启动的native进程
native 服务 | 代码位置 | 描述 |
---|---|---|
MediaServer | frameworks/av/media/mediaserver/main_mediaserver.cpp frameworks/av/media/mediaserver/mediaserver.rc |
mediaservice服务,mediaplayer的服务端 |
AudioServer | frameworks/av/media/audioserver/main_audioserver.cpp frameworks/av/media/audioserver/audioserver.rc |
启动AudioFlinger和AudioPolicyService |
SurfaceFlinger | frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp frameworks/native/services/surfaceflinger/surfaceflinger.rc |
显示系统 |
ServiceManager | /frameworks/native/cmds/servicemanager/service_manager.c /frameworks/native/cmds/servicemanager/servicemanager.rc |
注册binder的服务 |
这些服务启动的方式都差不多,以surfaceflinger为例:
LOCAL_INIT_RC
在frameworks/native/services/surfaceflinger/Android.mk中有如下的变量
LOCAL_INIT_RC := surfaceflinger.rc
编译宏LOCAL_INIT_RC用于将服务相关的RC文件编译到相应位置。上面的Android.mk通过LOCAL_INIT_RC将对应的surfaceflinger.rc编译到/system/etc/init目录中
解析对应的rc文件
是在system\core\init\init.cpp里面的main函数解析这些rc文件
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
} else {
parser.ParseConfig(bootscript);
parser.set_is_system_etc_init_loaded(true);
parser.set_is_vendor_etc_init_loaded(true);
parser.set_is_odm_etc_init_loaded(true);
}
service执行
init进程解析init.rc后,会将相应的action 放到队列中,之后会按action在action_queue这个队列中的顺序去执行操作
我们先看下surfaceflinger.rc的定义
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
surfaceflinger属于class core
调用class_start命令的地方在init.rc中,当执行boot action的时候,顺序执行就能执行到这个命令,首先启动的core一级别的服务
on boot
# Start standard binderized HAL daemons
class_start hal
class_start core
on nonencrypted
class_start main
class_start late_start
init进程最后会通过fork的方式去启动服务
孵化进程 -- Zygote
Android中大多数应用进程和系统进程都是通过Zygote进程来生成。Zygote为孵化的应用程序提供了几个基础资源:常用类,JNI函数,主题资源,共享库
Zygote主要做两件事:孵化应用进程,启动SystemServer.
Zygote启动后的大体流程如下:
Zygote启动过程分为native世界和java世界
native层的入口在
frameworks/base/cmds/app_process/app_main.cpp
java层的入口在
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
native层主要就是创建虚拟机,之后进入java世界,java层主要做四件事:注册socket,预加载资源,启动System Server,进入Loop循环。最后就是在loop循环中监听SystemServer的socket连接。
Android的“系统服务” -- SystemServer
SystemServer提供了众多的用java语言编写的系统服务,像AMS,PMS,以及WMS等都只是运行在system_server这个进程中的线程
SystemServer的路径在
frameworks/base/services/java/com/android/server/SystemServer.java
入口就是main函数
public static void main(String[] args) {
new SystemServer().run();
}
java的服务可以分成三类:
- BootstrapServices
Installer, AMS, Power Manager,Display Manager,PMS等 - CoreServices
DropBoxManagerService, BatteryService, UsageStatsService,WebViewUpdateService - OtherServices
这类数量最多,包括一些我们经常接触的如WMS,InputManagerService
SystemServer启动的服务很多,服务间也会有相互依赖的情况,为了解决依赖的时序问题,SystemServer主要通过分批启动和分阶段启动来处理。
主要利用了SystemServiceManager的startBootPhase(),
下面的图片拷贝自http://gityuan.com/2016/02/20/android-system-server-2/
这些启动阶段会穿插在各项的服务启动序列中。 startBootPhase会去回调用service的onBootPhase方法,对应的servcie才会去执行对应的操作
public void startBootPhase(final int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
Slog.i(TAG, "Starting phase " + mCurrentPhase);
service.onBootPhase(mCurrentPhase);
启动Launcher
在PHASE_SYSTEM_SERVICES_READY 之后,SystemServer会调用AMS的systemReady的方法, 改方法中就回去执行startactivity的流程
//phase480 && 500
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
...
mActivityManagerService.systemReady(() -> {
//phase550
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
//phase600
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}
}
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
traceLog.traceBegin("PhaseActivityManagerReady");
synchronized(this) {
if (mSystemReady) {
// If we're done calling all the receivers, run the next "boot phase" passed in
// by the SystemServer
if (goingCallback != null) {
goingCallback.run();
}
return;
}
startHomeActivityLocked(currentUserId, "systemReady");
}
AMS的systemReady会先执行参数Runnable,主要执行几个servcie的systemRunning方法,之后会去启动Launcher,Launcher启动后,会回调AMS的activityIdle, 最终会调用到AMS的finishBooting(),进入阶段Phase1000。