Android的系统启动
- Android有哪些比较主要的系统进程?
- 这些系统进程是如何启动的?
- 系统进程启动之后做了哪些事?
主要的系统进程
首先还是从启动配置文件init.rc中查找,这个文件中定义了很多Service,这些Service其实就是要单独启动的系统服务进程,以下我列了几个我们比较熟悉的。
service zygote /system/bin/app_process …
service servicemanager /system/bin/servicemanager …
service surfaceflinger /system/bin/surfaceflinger …
service media /system/bin/mediaserver …
由init进程启动的几个比较主要的进程有Zygote,Servicemanager,surfaceflinger;Android系统进程中还有一个比较主要的进程SystemServer,这个进程其实是由Zygote进程创建的。关于Zygote相关可查考 Zygote启动;别的主要系统服务详细介绍待写。
SystemServer
书接上回 Zygote启动;可以看到,Zygote通过forkSystemServer来创建是SystemServer的进程,代码如下:
// 代码来自Android23中:ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
......
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(...);
......
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
}
1.通过这个forkSystemServer来创建是SystemServer的进程。
2 创建SystemServer进程后,在这个进程里面执行这个handleSystemServerProcess,就是SystemServer启动的具体逻辑。
// 代码来自Android23中:ZygoteInit.java
private static void handleSystemServerProcess(...){
RuntimeInit.zygoteInit(......);
}
// 代码来自Android23中:RuntimeInit.java
public static final void zygoteInit(...){
commonInit();
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
handleSystemServerProcess主要代码就简单贴贴:
1 nativeZygoteInit这个函数的,主要是用于启用Binder机制,且启动了一个binder线程,因为Systemserver有很多系统服务都需要跟别的进程通信,比如我们的应用进程,比如ServiceManager等等。
2 applicationInit这个函数呢主要是调用SystemServer这个Java类的入口函数。
总结下上面的代码:
- Zygote创建SystemServer的进程
- 在SystemServer的进程中启用Binder机制
- 跳转到SystemServer.java的main方法
SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
// 代码来自Android23中:SystemServer.java
private void run() {
Looper.prepareMainLooper();
System.loadLibrary("android_servers");
createSystemContext();
startBootstrapServices();
startCoreServices();
startOtherServices();
Looper.loop();
}
- 为主线程创建一个Loop
- 加载这么一个共享库,系统服务它的native代码
- 创建一个系统上下文
- 分三批分别来加载系统服务
- 进入Loop循环
下面看两个问题:
- 系统服务要怎么发布才能让应用进程可见?
- 系统服务究竟跑在什么线程?
系统服务发布
// 代码来自Android23中:SystemService.java
public abstract class SystemService {
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
}
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
ServiceManager.addService(name, service, allowIsolated);
}
}
publishBinderService这个函数把系统服务它的binder注册到了ServiceManager中。
系统服务跑在什么线程
1). 有的服务有自己独有的工作线程,比如说咱们比较熟悉的AMS,PMS,还有PackageManagerService。
2).还有一些公用的工作线程:DisplayThread,FgThread,IoThread,UiThread,从名字上就能知道职责是什么;其中UiThread负责UI显示的,从这可以看出UI刷新不一定得再主线程,子线程也是可以的;还有一种就是Binder线程,也就是应用跨进程调用过来时是在Binder线程中的。
如何解决SystemServer启动过程中的服务依赖?
SystemServer启动过程中服务的这个相互依赖是怎么解决了,什么叫相互依赖呢?就是服务A需要用到服务B的一些东西,服务B又要用到服务C一些东西,那这样就形成了一个依赖关系,像SystemServer里面系统服务大概有七八十个了,你要完全解决这些服务之间错综复杂的依赖关系的其实不是一件容易的事,那么安卓他是怎么解决的呢?
-
分批启动
也就是前面源码中的三个start***Service(),比较基础的放前面,比如说AMS,PMS,PKMS等等,但很多service都需要依赖这几个Service。
-
分阶段启动
就是给启动分成不同的阶段,每到了一个阶段的就去通知当前已经启动了的service告诉他们现在到了什么阶段了,哪些资源又可以用;service就可以去做一些这个阶段里面可以做的初始化。
桌面的启动
- 在AMS服务就绪的时候会调用systemReady函数
// 代码来自Android23中:ActivityManagerService.java
public void systemReady(final Runnable goingCallback) {
......
startHomeActivityLocked(mCurrentUserId, "systemReady");
}
// 代码来自Android23中:ActivityManagerService.java
boolean startHomeActivityLocked(int userId, String reason) {
Intent intent = getHomeIntent();
......
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}
桌面其实你可以把它看成是一个单独的应用,系统级的应用;我们这是启动这个桌面的Activity。在Activity的onCreate里面呢,会启用一个LoaderTask,他会去向这个packagemanager去查询所有当前已经安装了这些应用,查询到了之后就把这些应用显示在桌面上,就是一个图标的方式,显示在桌面上,当我们点击了这些应用的图标之后呢,就会去启动这个应用的launchAcitivity
网友评论