前言
本来写了Activity和Service,应该继续写另外两个组件的,但是这里面会有很多重复内容,而且基本是触类旁通的,再照之前的方式写下去就未免有水文的嫌疑了。
后面有时间的话我再对其进行完整的梳理,那时候或许还有一读的价值。
本文要讲的系统的启动
init 进程 — 一切的开始
正如我们的程序会先走init方法一样,Android系统第一个进程是init,进程号为1, 它会进行Zygote,属性服务等的创建
系统的启动
安卓手机启动方式有BootLoader,Recovery等模式,默认按下电源键启动的是BootLoader,会执行系统的启动
Android系统的启动,也是linux系统的启动。
启动内核时,会执行设置缓存,加载驱动等步骤,然后查找init.rc文件(配置文件),并启动init进程
启动init进程
init的入口函数是main(),我们看下它的源码实现
system/core/init/init.cpp(安卓8,9)
int main(int argc , char** argv) {
....
bool is_first_stage = (getenv ("INIT_SECOND_STAGE") == nullptr);
if (is_first_stage) {
// 创建和挂载启动所需的文件目录
mount ("tmpfs","/dev","tmpfs" , MS NOSUID,"mode=0755") ;
...
}
....
//对属性服务进行初始化
property_init ();
...
// 启动属性服务
start_property_service();
...
if (bootscript.empty()) {
// 解析init.rc 配置文件
parser.ParseConfig ("/init.rc") ;
...
}
复制代码
安卓10开始这块代码有些不同,但大体流程是一样的,安卓11没有大变动
system/core/init/main.cpp(安卓10,11)
int main(int argc, char** argv) {
...
if (argc > 1) {
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap function_map;
return SubcontextMain(argc, argv, &function_map);
}
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);
}
// argc > 1 时启动第二阶段函数
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
// 启动第一阶段函数
return FirstStageMain(argc, argv);
}
复制代码
system/core/init/first_stage_init.cpp(安卓10,11)
int FirstStageMain(int argc, char** argv) {
...
// 创建和挂载启动所需的文件目录
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
....
return 1;
}
复制代码
system/core/init/init.cpp(安卓10,11)
int SecondStageMain(int argc, char** argv) {
...
// 对属性服务进行初始化
property_init();
...
// 启动属性服务
StartPropertyService(&epoll);
...
// 解析init.rc 配置文件
LoadBootScripts(am, sm);
...
return 0;
}
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
...
}
...
}
复制代码
可以知道init进程主要做了以下几件事情:
- 创建和挂载启动所需的文件目录
- 对属性服务进行初始化
- 启动属性服务
- 解析init.rc 配置文件, 启动Zygote进程
属性服务
属性服务用于记录用户、软件的一些使用信息,比如系统设置,以键值对存在,分为普通属性和控制属性
- 普通属性:如语言信息,wifi信息
- 控制属性:用来执行一些命令,比如开机动画
Zygote
Zygote又称孵化器,用于创建DVM(Dalvik虚拟机)和ART、应用程序进程以及运行系统的关键服务的SystemServer进程
工作原理
通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程。
Zygote的Java框架层中会创建一个Server端的Socket,这个Socket用来等待AMS请求Zygote来创建新的应用程序进程。
启动
Zygote的启动是在init.rc配置文件里面调用的,通过ro.zygote的属性选择引入脚本。主方法为main() 方法
system/core/rootdir/init.rc
import /init.${ro.zygote}.rc
on nonencrypted
class_start main
class_start late_start
复制代码
ro.zygote属性的取值有以下4种:
属性 | 说明 |
---|---|
init.zygote32.rc | 支持纯32位程序, |
init.zygote32_64.rc | 既支持32位程序也支持64位程序 |
init.zygote64.rc | 支持纯64位程序, |
init.zygote64_32.rc | 既支持32位程序也支持64位程序 |
init启动Zygote流程(过程有所简化)
Zygote进程启动
Zygote进程启动共做了如下几件事:
- 创建AppRuntime并调用其start方挂,启动Zygote进程。
- 创建Java虚拟机并为Java虚拟机注册JNI方法。
- 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
- 通过registerZygoteSocket方法创建服务器端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程。
- 启动SystemServer进程。
Zygote进程启动流程分析
Zygote的启动比较重要,这里啰嗦下,从源码角度分析下
AndroidRuntime启动Zygote
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;
// 创建JVM虚拟机
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
// 为JVM虚拟机注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
/*
* Start VM. This thread becomes the main thread of the VM, and will not return until the VM exits.
* className:com.android.internal.os.ZygoteInit
*/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
// 通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
复制代码
调用CallStaticVoidMethod方法之后进入了ZygoteInit的主方法,这一步开始进入Java框架层,后面的代码安卓10之后有所不同
ZygoteInit 初始化
这一步安卓10开始有所不同,安卓10之前通过registerServerSocket创建Socket,
安卓10开始则在ZygoteServer构造时创建Socket,但大体流程不变
安卓8,9源码
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
// 创建Server 端Socket ,socketName:"zygote"
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
...
// 预加载类和资源
preload(bootTimingsTraceLog);
...
} else {
Zygote.resetNicePriority();
}
...
if (startSystemServer) {
// 启动SystemServer进程(8.0为startSystemServer)
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// 等待AMS请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
复制代码
安卓10,11源码
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
if (!enableLazyPreload) {
...
// 预加载类和资源
preload(bootTimingsTraceLog);
...
} else {
Zygote.resetNicePriority();
}
// 创建Server端Socket
zygoteServer = new ZygoteServer(isPrimaryZygote);
...
if (startSystemServer) {
// 启动SystemServer进程(8.0为startSystemServer)
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// 等待AMS请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
复制代码
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}
mUsapPoolSupported = true;
fetchUsapPoolPolicyProps();
}
复制代码
SystemServer
SystemServer是由Zygote启动的进程,用于创建系统服务,如AMS,WMS,PMS等
SystemServer进程被创建后,主要做了如下工作:
- 启动Binder线程池,这样就可以与其他进程进行通信。
- 创建SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理。
- 启动各种系统服务。
Launcher
Launcher就是我们平时看到的桌面,由AMS启动,下篇文章会介绍下Launcher的启动流程
参考文献
[1]刘望舒.Android进阶解密[M]:电子工业出版社,2018-10