Android
系统是基于Linux
定制的一款开源的而移动端操作系统,由于其开源的特性,各大手机厂商可以针对其源码进行深度定制,对于开发者来说,有如此庞大且优秀的开源os
提供参考,尤其是对移动端的开发者来说,阅读Android
系统源码可以帮助我们更好地理解其中的各种机制,平时束手无策的问题也可以在源码中寻找答案。当然光8.0的源码就20多个g,像全部读完几乎是不可能的事,我们主要以framework
为主线,以系统运行机制为分支,层层阅读,剥开Android
系统的神秘面纱。
首先来一张google
经典的Android
系统架构图:可以看到,从上到下主要分为4层:应用层,framework
层,系统库和运行时,Linux
内核层。
#Android 启动流程
这里再上一张Android系统启动的流程图,可以看到系统从启动开始是按照一个流程:Loader
->kernel
->framework
->Application
来进行的。
Boot Rom
:当手机处于关机状态时,长按开机键开机,会引导芯片开始从固化在Rom里预设的代码开始执行,然后加载引导程序到Ram
Boot Loader
:启动Android系统之前的引导程序,主要是检查Ram
,初始化参数等Kernel
层指的就是Android内核层,这里一般开机刚刚结束进入Android系统,Kernel
层的启动流程如下:
swapper
进程(pid=0),这是系统初始化过程kernel创建的第一个进程,用于初始化进程管理、内存管理、加载Display
、Camera
、Binder
等驱动相关工作kthreadd
进程,这是Linux
系统的内核进程,会创建内核工作线程kworkder
、软中断线程ksoftirqd
和thermal
等内核守护进程。kthreadd
是所有内核进程的鼻祖。这里的native
层主要包括由init
进程孵化的用户空间的守护进程,bootanim
开机动画和hal
层等。Init
是Linux
系统的守护进程,是所有用户空间进程的鼻祖。
init
进程会孵化出ueventd
、logd
、healthd
、installd
、adbd
、lm这里写代码片
kd等用户守护进程;init
进程还会启动ServiceManager
(Binder服务管家)、bootanim
(开机动画)等重要服务。init
进程孵化出Zygote
进程,Zygote
进程是Android系统第一个Java进程(虚拟机进程),Zygote
进程是所有Java进程的父进程。framework
层有native
层和java
层共同组成,协调系统平稳有序的工作。framework
层主要包括以下内容:
Media Server
进程,是由init
进程fork
而来,负责启动和管理整个C++ framework
,包含AudioFlinger
,Camera Service
等服务。Zygote
进程,由Init
进程通过解析init.rc
文件生成,Zygote
是Android系统的第一个Java进程,是所有Java进程的父进程。System Server
进程,由Zygote
进程fork
而来,是Zygote
进程孵化的第一个子进程,负责启动和管理整个Java Framework
,包括Ams
、Pms
等。Zygote
进程孵化的第一个App
进程是Launcher
进程,也就是我们的桌面进程,也就是我们打开手机看到的用户界面。因为在前面的framework
生成了各种守护进程和管理进程,对于Launcher
也就有对应的点击、长按、滑动、卸载等监听。Zygote
进程也会创建Browser
、Phone
、Email
等App进程。也就是说所有的App进程都是由Zygote
进程fork
生成的。而且上层的进程全部由下层的进程进行管理,包括但不限于界面的注册、跳转,消息的传递。
了解了Android
系统从按下开机键到桌面完整运行在用户眼前的整个流程,我们就可以针对系统的各个过程进行分析。由于是移动开发,平时最多打交道的是应用层,也是就上面的App
层,跟我们打交道最多的就是framework
层,我们主要关注framework
层是如何启动并调度各应用进程协调工作的。从ZygoteInit
的main
方法开始,我们先看framework
启动流程的时序图(省略了一些步骤)大体如下:
[外链图片转存失败(img-Gm3OOCcd-1568628095444)(http://on-img.com/chart_image/5b694cb9e4b025cf4939ddf2.png)]
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
...
try {
// Report Zygote start time to tron unless it is a runtime restart
if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
MetricsLogger.histogram(null, "boot_zygote_init",
(int) SystemClock.elapsedRealtime());
}
...
// 1.加载首个Zygote进程的时候,加载参数有start-system-server,即startSystemServer=true
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
// 2. 注册zygote服务端localserversocket
zygoteServer.registerServerSocket(socketName);
...
// 3.在这里开启了SystemServer,也就是Ams,Pms,Wms...等一系列系统服务
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
// 4.while(true) 死循环,除非抛出异常系统中断
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
ZygoteInit.main()
由native
层传入初始化参数调用,这里不再赘述,这边主要沿Java的framework
层来分析系统的调用,结合上图和代码注释可以看到,加载参数有start-system-server,即startSystemServer=true赋值,紧接着下面会调用ZygoteServer.registerServerSocket()
,也就是这里和ZygoteServer
的通信用到的是LocalSocket
,我们知道跨进程调用最常见的调用方式就是LocalSocket
和aidl
,在framework
里也有很多这样通信的。接下来就开启了SystemServer
,后面是一个runSelectLoop()
,这里其实是一个死循环,当抛出异常终止则会调用zygoteServer.closeServerSocket()
来关闭socket
连接。我们继续跟进startSystemServer
看具体是如何开启系统服务的。
/**
* Prepare the arguments and fork for the system server process.
*/
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 {
//传入准备参数,注意上面参数最后的"com.android.server.SystemServer"
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
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 */
// pid = 0 说明创建子进程成功,SystemServer此时拥有独立进程,可以独立在自己的进程内操作了
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
// 处理SystemServer进程
handleSystemServerProcess(parsedArgs);
}
return true;
}
这个方法不是很长,看注释可以知道,主要是用来准备SystemServer
进程的参数和forkSystemServer
进程。前面一堆参数不用看,注意我添加中文注释的地方,传入的参数有一个内容为"com.android.server.SystemServer"
,这是SystemServer
类的全限定名,接下来调用Zygote.forkSystemSeerver()
,最后当pid=0
时,也就是说明子进程创建成功,如果这时候有两个Zygote
进程则等待第二个Zygote
进程连接,关闭掉第一个Zygote
进程和ZygoteServer
的socket
连接。最后调用handleSystemServerProcess()
来处理SystemServer
进程。这里的Zygote.forkSystemServer()
实际上是调用了native
层的forkSystemServer()
来fork子进程。这里主要跟进handleSystemServerProcess()
看看是如何完成新fork的SystemServer
进程的剩余工作的。
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
...
// 默认为null,走Zygote.init()流程
if (parsedArgs.invokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
// 创建类加载器,并赋予当前线程
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
parsedArgs.invokeWith
默认是为null的,也就是走else
流程,可以看到先创建了一个类加载器并赋予了当前线程,这个类加载器用来加载android application等类,后续的Android
相关dex
加载都是用的这个classloader
。然后进入了ZygoteInit.zygoteInit()
。
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in nativeFinishInit()
* were rationalized with Zygote startup.
*
* Current recognized args:
*
* -
[--] <start class name> <args>
*
*
* @param targetSdkVersion target SDK version
* @param argv arg strings
*/
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
// Zygote初始化
ZygoteInit.nativeZygoteInit();
// 应用初始化
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
这个方法不是很长,主要工作是Zygote
的初始化和Runtime
的初始化。Zygote
的初始化调用了native
方法,里面的大致工作是打开/dev/binder
驱动设备,创建一个新的binder
线程,调用talkWithDriver()
不断地跟驱动交互。
进入RuntimeInit.applicationInit()
查看具体应用初始化流程。
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
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);
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
这个方法也不是很长,前面的一些配置略过,主要看解析参数和invokeStaticMain()
,顾名思义,这里的目的是通过反射调用静态的main方法,那么调用的是哪个类的main
方法,我们看传入的参数是args.startClass
,我们追溯参数的传递过程,发现之前提到的一系列args
被封装进ZygoteConnection.Arguments
类中,这一系列参数原本是
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",
};
可以看到,唯一的类的全限定名是com.android.server.SystemServer
,追述args = new Arguments(argv)
的源码也可以找到答案:
Arguments(String args[]) throws IllegalArgumentException {
parseArgs(args);
}
private void parseArgs(String args[])
throws IllegalArgumentException {
int curArg = 0;
for (; curArg < args.length; curArg++) {
String arg = args[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
}
}
if (curArg == args.length) {
throw new IllegalArgumentException("Missing classname argument to RuntimeInit!");
}
// startClass 为args的最后一个参数
startClass = args[curArg++];
startArgs = new String[args.length - curArg];
System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
}
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.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 Zygote.MethodAndArgsCaller(m, argv);
}
可以看到,这边走的就是正常的一个反射流程,会对main
方法的参数、修饰符等校验,有问题抛出RuntimeException
运行时异常,没问题就抛出一个Zygote.MethodAndArgsCaller
,这一步的处理可以说是非常奇怪了,既然执行完毕为什么不直接invoke而是抛出异常呢,我们可以看到英文注释的大概解释,这个异常抛出在ZygoteInit.main()
方法,执行了异常的run方法,其目的是清除设置中的所有堆栈帧,既然如此我们回到ZygoteInit.main()
方法,果然:
try{
...
}catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
}
抛出该异常调用了caller.run()
方法,那我们看这里做了什么:
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
可以看到,这里调用了mMethod.invoke(null, new Object[] { mArgs })
,也就是执行了SystemServer
的main
方法。
public static void main(String[] args) {
new SystemServer().run();
}
try {
...
//主线程在当前进程
Looper.prepareMainLooper();
...
// 初始化系统上下文
createSystemContext();
// 1.创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd();
}
...
try {
traceBeginAndSlog("StartServices");
//2.开启一些重要的系统服务
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
可以看到,这边主要的工作,创建主线程Looper
循环器,初始化系统上下文,最关键的还是后面的开启一系列的服务,这些服务就包括了系统服务,跟进sartBootstrapService()
看看是如何初始化系统服务的。
...
SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
// 阻塞等待与installd建立socket通道
Installer installer = mSystemServiceManager.startService(Installer.class);
// 1. 在这里开启了Ams
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
...
// 2.在这里开启了PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// 3.Ams 初始化PowerManager
mActivityManagerService.initPowerManagement();
// Bring up recovery system in case a rescue party needs a reboot
if (!SystemProperties.getBoolean("config.disable_noncore", false)) {
traceBeginAndSlog("StartRecoverySystemService");
//
mSystemServiceManager.startService(RecoverySystemService.class);
traceEnd();
}
mSystemServiceManager.startService(LightsService.class);
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
可以看见启动了很多的系统服务,其中很多的服务目前也不是很了解,主要的是ActivityMangerService
和PackageManagerService
等主要管理系统的一些服务。自此,Android系统的SystemServer
已经启动,并且其相关的各种系统服务已经启动,Ams
等重要系统服务也均已开启。Ams
是贯穿Android系统的核心服务,负责系统四大组件的启动、切换及其生命周期管理和调度等工作,各个应用程序App作为独立进程需要通过Binder
与Ams
进行通信,而Ams
在SystemServer
中通过LocalSocket
与Zygote
进行通信。不管是对于系统运行的原理,还是各组件的调度过程,理解Ams
的工作原理十分重要,接下来将以此为主线,分别分析Ams
、四大组件等的启动流程和生命周期的管理等。
Android 8.0.1源码
Android系统开篇
Android系统启动过程深入分析