Android系統(tǒng)的Zygote進(jìn)程是所有的android進(jìn)程的父進(jìn)程,包括SystemServer和各種應(yīng)用進(jìn)程都是通過Zygote進(jìn)程fork出來的贡羔。而Zygote進(jìn)程則是通過Linux系統(tǒng)的init進(jìn)程啟動的卒密;
android系統(tǒng)中各種進(jìn)程的啟動方式:
init進(jìn)程 –> Zygote進(jìn)程 –> SystemServer進(jìn)程 –>各種應(yīng)用進(jìn)程
- init進(jìn)程:linux的根進(jìn)程近弟;android系統(tǒng)是基于linux系統(tǒng)的鉴嗤,因此可以算作是整個android操作系統(tǒng)的第一個進(jìn)程盟劫;
- Zygote進(jìn)程:android系統(tǒng)的根進(jìn)程;主要作用:fork出SystemServer進(jìn)程和各種應(yīng)用進(jìn)程商架;
- SystemService進(jìn)程:主要是在這個進(jìn)程中啟動系統(tǒng)的各項服務(wù)堰怨,比如ActivityManagerService,PackageManagerService蛇摸,WindowManagerService服務(wù)等等备图;
- 各種應(yīng)用進(jìn)程:啟動自己編寫的客戶端應(yīng)用時,一般都是重新啟動一個應(yīng)用進(jìn)程赶袄,有自己的虛擬機(jī)與運行環(huán)境揽涮;
本文主要介紹一下Zygote進(jìn)程的啟動流程,關(guān)于SystenServer進(jìn)程和各種應(yīng)用進(jìn)程的啟動方式會在以后的文章中介紹弃鸦。
1. Zygote類的main方法
init進(jìn)程在啟動Zygote進(jìn)程時一般都會調(diào)用ZygoteInit類的main方法绞吁,因此我們這里看一下該方法的具體實現(xiàn)(基于android23源碼);
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;
}
}
- 第一行是調(diào)用enableDdms()唬格,設(shè)置DDMS可用;可以發(fā)現(xiàn)DDMS啟動的時機(jī)還是比較早的颜说,在整個Zygote進(jìn)程剛剛開始要啟動額時候就設(shè)置可用了购岗;
- 下面的循環(huán)主要是解析main方法的參數(shù)獲取是否需要啟動SystemService進(jìn)程、獲取abi列表门粪、獲取scoket連接名稱 喊积;
(這里需要注意的是:android系統(tǒng)中進(jìn)程之間通訊的方式是Binder,但是有一個例外是SystemService進(jìn)程與Zygote進(jìn)程之間是通過Socket的方式進(jìn)行通訊的) - 然后調(diào)用registerZygoteSocket(String socketName)為Zygote進(jìn)程注冊socket:
2. main方法中調(diào)用的registerZygoteSocket方法
作用是為Zygote進(jìn)程注冊socket
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);
}
}
}
3. 接著調(diào)用系統(tǒng)方法preLoad()
通過Zygote fork出SystemServer進(jìn)程:
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()用于初始化系統(tǒng)資源乾吻;
preloadOpenGL()用于初始化OpenGL;
preloadSharedLibraries()用于初始化系統(tǒng)libraries拟蜻;
preloadTextResources()用于初始化文字資源绎签;
prepareWebViewInZygote()用于初始化webview;
4. 然后調(diào)用startSystemServer(abiList, socket)方法
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;
}
** 總結(jié): **
Zygote進(jìn)程mian方法主要執(zhí)行邏輯:
- 初始化DDMS;
- 注冊Zygote進(jìn)程的socket通訊酝锅;
- 初始化Zygote中的各種類诡必,資源文件,OpenGL搔扁,類庫爸舒,Text資源等等蟋字;
- 初始化完成之后fork出SystemServer進(jìn)程;
- fork出SystemServer進(jìn)程之后扭勉,關(guān)閉socket連接鹊奖;