Zygote进程启动流程(转)

Zygote进程启动流程(转)

大家都知道android系统的Zygote进程是所有的android进程的父进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。Zygote(孵化)进程相当于是android系统的根进程,后面所有的进程都是通过这个进程fork出来的,而Zygote进程则是通过linux系统的init进程启动的,也就是说,android系统中各种进程的启动方式

init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程

  • init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;

  • Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;

  • SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;

  • 各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;

本文主要介绍一下Zygote进程的启动流程,关于SystenServer进程和各种应用进程的启动方式会在以后的文章中介绍。

init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法,因此我们这里看一下该方法的具体实现(基于android23源码);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public static void main(String argv[]) {
try {
RuntimeInit.enableDdms();
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();

boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = 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.");
}

registerZygoteSocket(socketName);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());

// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();

// Do an initial gc to clean up after startup
gcAndFinalize();

// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);

if (startSystemServer) {
startSystemServer(abiList, socketName);
}

Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList);

closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
  • 第一行主要是调用enableDdms(),设置DDMS可用,可以发现DDMS启动的时机还是比较早的,在整个Zygote进程刚刚开始要启动额时候就设置可用了。

  • 下面的循环主要是解析main方法的参数获取是否需要启动SystemService进程,获取abi列表,获取scoket连接名称
    (这里需要注意的是:android系统中进程之间通讯的方式是Binder,但是有一个例外是SystemService进程与Zygote进程之间是通过Socket的方式进行通讯的)

  • 然后调用registerZygoteSocket(String socketName)为Zygote进程注册socket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}

try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
  • 接着调用系统方法preLoad()
1
2
3
4
5
6
7
8
9
10
11
12
static void preload() {
Log.d(TAG, "begin preload");
preloadClasses();
preloadResources();
preloadOpenGL();
preloadSharedLibraries();
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
Log.d(TAG, "end preload");
}

这其中:
preloadClasses()用于初始化Zygote中需要的class类;
preloadResources()用于初始化系统资源;
preloadOpenGL()用于初始化OpenGL;
preloadSharedLibraries()用于初始化系统libraries;
preloadTextResources()用于初始化文字资源;
prepareWebViewInZygote()用于初始化webview;

  • 然后调用startSystemServer(abiList, socket);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
/* 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,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {
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 */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}

handleSystemServerProcess(parsedArgs);
}

return true;
}

可以看到这段逻辑的执行逻辑就是通过Zygote fork出SystemServer进程。

总结:
Zygote进程mian方法主要执行逻辑:

  • 初始化DDMS;

  • 注册Zygote进程的socket通讯;

  • 初始化Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;

  • 初始化完成之后fork出SystemServer进程;

  • fork出SystemServer进程之后,关闭socket连接;

另外对android源码解析方法感兴趣的可参考我的:

android源码解析之(一)–>android项目构建过程

android源码解析之(二)–>异步消息机制

android源码解析之(三)–>异步任务AsyncTask

android源码解析之(四)–>HandlerThread

android源码解析之(五)–>IntentService

android源码解析之(六)–>Log

android源码解析之(七)–>LruCache

发布于

2022-08-06

更新于

2022-08-06

许可协议

评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...