笔记:Zygote和SystemServer进程启动过程
简述
Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程。
Zygote就是进程init启动起来的。Android中所有应用程序进程,以及运行系统关键服务的System进程都是由Zygote创建的。它通过复制自身的形式创建其它进程。Zygote在启动时会在内部创建一个虚拟机实例,因此,通过复制Zygote得到的其它应用程序进程和System进程都可以快速地在内部获得一个虚拟机地拷贝。Zygote启动完成后就立即将System进程启动,以便各种关键服务被启动运行。
Zygote的启动
它以服务的形式被启动。
创建虚拟机
进程内创建一个虚拟机实例,并注册一系列JNI方法。
frameworks/base/core/jni/AndroidRuntime.cpp
/* start the virtual machine. */
startVM(&mJavaVM, &env);
/* Register android functions. */
startReg(env);
接下来执行“com.android.internal.os.ZygoteInit”Java类的main方法继续执行启动。
ZygoteInit.main
package com.android.internal.os;
import android.net.LocalServerSocket;
...
public class ZygoteInit {
private static LocalServerSocket sServerSocket;
public static void main(String argv[]) {
...
registerZygoteSocket();
...
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
...
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
...
closeServerSocket();
...
}
}
创建Socket
Zygote调用registerZygoteSocket();创建一个LocalServerSocket sServerSocket的Server端Socket,等待以后运行在System进程中的服务ActivityManagerService创建的Client端Socket连接,然后通过Socket进程间通信通知Zygote创建新的应用程序进程。
创建System进程
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--capabilities=130104352,130104352",
"--rlimit=8,",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
...
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, rlimits,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
变量args保存启动System进程的参数。
Zygote.forkSystemServer()复制当前进程来创建子进程。
handleSystemServerProcess()继续处理System进程的启动。
轮询等待AMS请求创建App进程
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
...
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
/**
* Waits for and accepts a single command connection. Throws
* RuntimeException on failure.
*/
private static ZygoteConnection acceptCommandPeer() {
try {
return new ZygoteConnection(sServerSocket.accept());
} catch (IOException ex) {
throw new RuntimeException(
"IOException during accept()", ex);
}
}
无限循环,等待来自AMS创建的Socket连接。
sServerSocket在fds[0]位置。
每当accept()返回一个连接后,将对应此连接的newPeer.getFileDesciptor()套接字描述添加到fds(第0位置后),下一次读取到数据时,若在fds[0]以后的,说明是前面的newPeer连接收到的AMS的创建新应用程序进程的请求。
runOnce()用来处理AMS创建新应用程序进程的请求。
System进程的启动
ZygoteInit.handleSystemServerProcess()执行System进程的启动操作。
ZygoteInit.handleSystemServerProcess()
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}
Zygote复制自身创建的子进程做为System进程,这样它得到了Zygote的Server Socket,但是用不到,所以第一句closeServerSocket()关闭此套接字。
RuntimeInit.zygoteInit
package com.android.internal.os;
public class RuntimeInit {
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
...
commonInit();
zygoteInitNative();
...
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
}
zygoteInitNative()在System进程中启动一个Binder线程池。
RuntimeInit.invokeStaticMain()静态方法调用"com.android.server.SystemServer"的main方法。
SystemServer.main
传递调用native方法init1():
class SystemServer {
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
}
init1()的工作:
注册Service Manager的死亡通知:调用binderDied()。System进程执行kill结束自己。
创建SurfaceFlinger、和SensorService两个服务。
返回SystemServer.init2()继续启动java语言开发的系统服务。
SystemServer.init2
public static final void init2() {
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
ServerThread继承自Thread。
ServerThread.run
class ServerThread extends Thread {
@Override
public void run() {
Looper.prepare();
...
// Critical services...
try {
...
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
...
Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);
...
Slog.i(TAG, "Content Manager");
ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
...
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
((ActivityManagerService)ServiceManager.getService("activity"))
.setWindowManager(wm);
...
} catch (RuntimeException e) {
Slog.e("System", "Failure starting core service", e);
}
...
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
}
启动各个Service然后注册到ServiceManager。
各个服务都使用Binder和其它服务使用者进程进行就行交互。
(本文使用Atom编写)
笔记:Zygote和SystemServer进程启动过程的更多相关文章
- Android系统启动流程(三)解析SystemServer进程启动过程
1.Zygote启动SystemServer进程 在上一篇文章中我们讲到在ZygoteInit.java的startSystemServer函数中启动了SyetemServer进程,如下所示. fra ...
- Zygote及System进程启动
1. init 根据init.rc 运行 app_process, 并携带‘--zygote' 和 ’--startSystemServer' 参数. 2. AndroidRuntime.cpp: ...
- Android应用程序进程启动过程(前篇)
在此前我讲过Android系统的启动流程,系统启动后,我们就比较关心应用程序是如何启动的,这一篇我们来一起学习Android7.0 应用程序进程启动过程,需要注意的是“应用程序进程启动过程”,而不是应 ...
- Android应用程序进程启动过程的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址: http://blog.csdn.net/luoshengyang/article/details/6747696 Android 应用程序框架层创 ...
- Android应用程序进程启动过程(后篇)
前言 在前篇中我们讲到了Android应用程序进程启动过程,这一篇我们来讲遗留的知识点:在应用程序进程创建过程中会启动Binder线程池以及在应用程序进程启动后会创建消息循环. 1.Binder线程池 ...
- Android系统启动流程(二)解析Zygote进程启动过程
1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器.它通过 ...
- Android系统启动流程(一)解析init进程启动过程
整体流程大致如下: 1.init简介 init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等.in ...
- Linux进程启动过程简析
朱宇轲 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 今天,我们将通过 ...
- Android(java)学习笔记161:Framework运行环境之启动SystemServer进程
SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的.与启动普通进程的差别 ...
随机推荐
- systemd 编写服务管理脚本---学习
转载:https://www.cnblogs.com/sparkdev/p/8521812.html 我们运行 linux 服务器的主要目的是通过运行程序提供服务,比如 mysql.web serve ...
- django后台对某些字段设置颜色
在model.py的class函数中添加如下代码 #对签收状态设置颜色 def color_state(self): ': assign_state_name = '待签收' color_code = ...
- PHP+Mysql 实现数据库增删改查(原生)
Mysql数据库创建 创建一个新闻列表的数据库: 1. 查询数据库 1.1. 创建文件dbconfig.php,保存常量 <?php define("HOST"," ...
- LCMapString/LCMapStringEx实现简体字、繁体字的转换。
c#环境下想要最小程度不使用第三方库.程序性能,于是选择了这个Windows API. 转载自https://coolong124220.nidbox.com/diary/read/8045380 对 ...
- ArrayList的ConcurrentModificationException异常和多线程下的异常
一.ConcurrentModificationException ArrayList源码看为什么出现异常: public class ArrayList<e> extends Abstr ...
- python生成器 获取 目录下文件
# os.walk()和os.list 都是得到所有文件的列表, 如果目录下文件特别多, 上亿了, 我们就需要生成器的方式获取 # 要求目录下面没有目录, 会递归到子目录下面找文件, (如果有子目录可 ...
- 【aardio】回车换行符
回车换行符 在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符.但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字 ...
- 四、PyQt5布局管理(绝对&相对、水平、垂直、格栅、表单)
目录 一.绝对布局 二.盒布局 三.格栅布局 四.格栅布局跨行跨列显示 布局管理即设置窗体上各个控件的位置,对于新手来说,这是学习的难点. 布局管理根据绝对坐标是否变动分为绝对布局和相对布局两大类.采 ...
- C++题解:Matrix Power Series ——矩阵套矩阵的矩阵加速
Matrix Power Series r时间限制: 1 Sec 内存限制: 512 MB 题目描述 给定矩阵A,求矩阵S=A^1+A^2+--+A^k,输出矩阵,S矩阵中每个元都要模m. 数据范围: ...
- HTML的Tomcat
修改D:\software\apache-tomcat-8.0.44\webapps\ROOT\WEB-INF\web.xml: <?xml version="1.0" en ...