Zygote進程基礎介紹java
Zygote中文翻譯爲「受精卵」,正如其名,它主要用於孵化子進程。在Android系統中有如下兩種程序:
1. java應用程序,主要基於ART虛擬機,全部的應用程序apk都屬於這類
2. native程序,也就是利用C或C++語言開發的程序,如bootanimation。android
全部的Java應用程序進程及系統服務SystemServer進程都由Zygote進程經過Linux的fork()函數孵化出來的,這也就是爲何把它稱爲Zygote的緣由,由於他就像一個受精卵,孵化出無數子進程,而native程序則由Init程序建立啓動。Zygote進程最初的名字不是「zygote」而是「app_process」,這個名字是在Android.mk文件中定義的。數組
如圖所示爲Zygote孵化框架:app
Zygote是一個C/S模型,Zygote進程做爲服務端,其餘進程做爲客戶端向它發出「孵化」請求,而Zygote接收到這個請求後就「孵化」出一個新的進程。如圖所示,當點擊Launcher裏的應用程序圖標去啓動一個新的應用程序進程時,這個請求會到達框架層的核心服務ActivityManagerService中,當AMS收到這個請求後,它經過調用Process類發出一個「孵化」子進程的Socket請求,而Zygote監聽到這個請求後就馬上fork一個新的進程出來。
Zygote進程的啓動框架
Zygote進程對應的主文件爲app_main.cpp,當他被Init進程啓動起來以後,就會進入主文件app_main.cpp的main()函數。接下來它的main函數開始分析Zygote進程的啓動:socket
int main(int argc, char* const argv[])
{
.......
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
//說明啓動的是Zygote進程
niceName = ZYGOTE_NICE_NAME;
//ZYGOTE_NICE_NAME字符串內容就是「Zygote」,此處已被換名字
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
//在init.rc裏配置了前面的這些參數,而Zygote進程啓動的時候,
//Init進程會傳過來這些參數,因此此處把變量startSystemServer
//設置爲true表明啓動SystemServer
} else if (strcmp(arg, "--application") == 0)
.......
}
......ide
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
//zygote爲true表明的是Zygote進程,也就是說如今正在啓動的是Zygote進程,
//咱們知道Zygote進程用於孵化子進程,Zygote進程孵化子進程是經過本身的資源賦值一份,
//來fork一個新的子進程,也就是說子進程也會進入這個文件的main函數,所以,
//這裏的main函數被調用並不僅是Zygote啓動的時候被調用。這裏經過zygote這個變量來區分,
//若是是Zygote進程自己,就會進入到if裏,不然就會進入到下面的else if裏,表明字進程啓動。
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
.......
}
}函數
main()函數最後調用runtime的start()函數,runtime是一個AppRuntime對象,看看AppRuntime類:oop
class AppRuntime : public AndroidRuntime
{
.......
}post
AppRuntime類繼承AndroidRuntime類,所以前面調用的runtime的start()函數就會進入AndroidRuntime的start()函數,下面看看該函數:
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//啓動VM
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//註冊JNI函數
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
....
//className由上一步傳遞過來,「com.android.internal.os.ZygoteInit」或者「com.android.internal.os.RuntimeInit」
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
//代表要調用的是類的main()函數
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
//調用ZygoteInit的main()函數或RuntimeInit的main()函數
env->CallStaticVoidMethod(startClass, startMeth, strArray);
.......
}
AndroidRuntime的start()函數主要作了如下三件事情:
1. 調用startVM()函數啓動虛擬機
2. 調用startReg()函數註冊JNI方法
3. 調用com.android.internal.os.ZygoteInit類的main()函數(如果子進程,則調用com.android.internal.os.RuntimeInit的main()函數,從而基本結束初始化。而Zygote進程的main函數則還有如下的會講到的5項工做)
下面一一介紹三個函數的具體工做:
啓動虛擬機
經過調用startVM()函數啓動虛擬機:
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
......
//經過調用JNI_CreateJavaVM()建立虛擬機,若是對這個感興趣,能夠去研究下art虛擬機
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\n");
return -1;
}
......
}
註冊JNI方法
在Android中,Java世界要調用native世界的函數就要用JNI機制,而且在Android系統中也大量使用JNI機制,Android系統經過以下的startReg()函數去註冊:
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
......
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
.......
}
startReg()函數經過調用register_jni_procs()函數去進一步註冊,傳遞的值是gRegJNI數組,原生Android6.0版本該數組超過130個,具體以下:
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
REG_JNI(register_android_util_PathParser),
REG_JNI(register_android_app_admin_SecurityLog),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
REG_JNI(register_android_text_AndroidCharacter),
REG_JNI(register_android_text_StaticLayout),
REG_JNI(register_android_text_AndroidBidi),
REG_JNI(register_android_view_InputDevice),
REG_JNI(register_android_view_KeyCharacterMap),
REG_JNI(register_android_os_Process),
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
......
}
上面所列的JNI都經過register_jni_procs()函數來註冊:
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
return -1;
}
}
return 0;
}
經過循環對全部的JNI函數進行註冊。。。
調用ZygoteInit類的main()
ZygoteInit是一個Java類,咱們終於走到了Java世界,看看該main()方法:
public static void main(String argv[]) {
......
try {
......
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
........
zygoteServer.registerServerSocket(socketName);
.......
preload(bootTimingsTraceLog);
.......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process.
if (r != null) {
r.run();
return;
}
}
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
.....
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
ZygoteInit類的main()方法主要作了如下5項工做:
1. 調用ZygoteServer類的registerServerSocket()方法建立一個Zygote的Socket接口,用來和AMS通訊
2. 調用preload()預加載類和資源
3. 調用forkSystemServer()函數來啓動SystemServer進程,r.run()啓動其main()方法
4. 調用ZygoteServer類的runSelectLoop()函數在前面建立的Socket接口上進入一個無限循環,等待覈心服務AMS請求建立新的應用程序進程。
5. 調用caller.run()方法,啓動子進程直接進入子進程的main()方法(非system_server進程,該進程由r.run()啓動main()方法)
下面一一講解着五項工做的內容:
registerServerSocket()
經過調用ZygoteServer類的registerServerSocket()方法來建立一個Java層的LocalServerSocket對象,目的是等待建立新的應用程序進程請求:
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
.......
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
.......
}
}
}
preload()預加載類與資源
static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
.......
//加載類,經過反射加載framework下的preload-classes文件中的類
preloadClasses();
......
//加載資源,加載framework-res-apk的資源
preloadResources();
//這兩個方法比較耗時,Android啓動時間慢,這是其中一個緣由,加載的類和資源太多了,致使時間過長。
//提供一種思路去優化開機速度,既然這兩個方法時間過長,就單獨開一個線程去執行它,不要放在這個主線程裏,能夠試試
......
//加載OpenGL()
preloadOpenGL();
.....
//加載共享庫
preloadSharedLibraries();
.....
}
既然加載這些類和資源這麼耗時間,爲何還要預加載:
應用程序都從Zygote孵化出來,應用程序都會繼承Zygote的全部內容,若是在Zygote啓動的時候加載這些類和資源,這些孵化的應用程序就繼承Zygote的類和資源,這樣啓動引用程序的時候就不須要加載類和資源了,啓動的速度就會快不少。開機的次數很少,可是啓動應用程序的次數很是多。
啓動SystemServer進程
後續咱們將分析啓動SystemServer進程,主要是比較啓動SystemServer進程與啓動普通應用程序進程的區別。
runSelectLoop()函數進入無限循環
Runnable runSelectLoop(String abiList) {
.......
while (true) {
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
......
}
.......
}
在無限循環中,若是變量i==0,表示Zygote Socket服務尚未準備好;當i!=0時,表示正在等待客戶端來鏈接「Zygote」這個Socket。當有孵化子進程的請求時,就會調用ZygoteConnection類的processOneCommand()函數來建立子進程。
caller.run()函數
咱們將在啓動應用程序進程的時候分析caller.run()函數。
SystemServer進程
啓動syetem_server進程
從上面的學習可知,啓動系統服務system_server進程從ZygoteInit.java的main()方法調用forkSystemServer()方法開始,先看看該方法:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
.....
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",
};
.......
try {
......
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
.......
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
首先設置了system_server進程的uid。gid和groups,而後設置進程的名字爲」–nice-name=system_server」。接着調用forkSystemServer()函數來fork一個新的進程,他有兩個返回值,一個在當前進程中返回,另外一個在新建立的進程中返回,在當前進程中返回值是新建立的pid值,而新建立進程中的返回值是0。
若是pid==0,表示已經進入SystemServer子進程,因而先調用zygoteServer.closeServerSocket()關閉「Zygote」socket,因爲Zygote啓動過程當中建立一個「Zygote」Socket。而系統服務進程system_server也繼承了Socket,不用因此close它。接着調用了handleSystemServerProcess()方法:
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
.......
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
.......
}
主要調用了ZygoteInit.zygoteInit()方法:
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
zygoteInit()方法主要調用了ZygoteInit.nativeZygoteInit()和RuntimeInit.applicationInit()這兩個方法:
- nativeZygoteInit()主要執行Binder驅動程序初始化的相關工做,它調用以後system_server進程就能夠進行Binder進程通訊(),是個native方法。
- 調用applicationInit()方法主要是爲了進入SystemServer.java的main()方法
接下來看看RuntimeInit.applicationInit()方法:
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
........
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
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) {
..........
return new MethodAndArgsCaller(m, argv);
}
能夠看出applicationInit()方法調用findStaticMain()方法,而該方法經過反射獲取system-server的main()方法後返回一個MethodAndArgsCaller,這是一個Runnable:
static class MethodAndArgsCaller 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) {
.......
}
}
}
可見經過反射調用main()方法,但返回到哪呢?其實在上面的ZygoteInit類的main()方法中,在建立完system_server後直接調用,以下ZygoteInit類的main()方法代碼所示,Runnable類型的r調用r.run()方法:
public static void main(String argv[]) {
......
try {
........
zygoteServer.registerServerSocket(socketName);
.......
preload(bootTimingsTraceLog);
.......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process.
if (r != null) {
r.run();
return;
}
}
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
.....
} finally {
zygoteServer.closeServerSocket();
}
if (caller != null) {
caller.run();
}
}
SystemServer fork新進程
Init進程、Zygote進程和SystemServer進程都很是重要,由於任何一個死機否會出現重啓。從上面的講解中可知,SystemServer系統服務的啓動從ZygoteInit類的forkSystemServer()方法開始:
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
.....
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",
};
.......
try {
......
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
.......
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
主要調用了兩個方法,Zygote.forkSystemServer()和handleSystemServerProcess(),上面講解了handleSystemServerProcess(),如今主要分析Zygote.forkSystemServer():
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
主要調用了nativeForkSystemServer(),這是一個native方法,對應的實現以下:
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL, NULL);
//傳入了衆多參數來fork一個新的進程
if (pid > 0) {
ALOGI("System server process %d has been created", pid);
gSystemServerPid = pid;
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}
主要調用了ForkAndSpecializeCommon()函數:
static pid_t ForkAndSpecializeCommon(......) {
.....
pid_t pid = fork();
......
UnsetSigChldHandler();
......
}
主要調用了兩個函數,fork()函數來建立一個新的子進程,接下來看看UnsetSigChldHandler():
static void SetSigChldHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SigChldHandler;
int err = sigaction(SIGCHLD, &sa, NULL);
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
SetSigChldHandler()設置了信號處理函數SigChldHandler,意思是子進程死亡以後,就會產生一個信號,Zygote進程受到該信號以後就會調用SigChldHandler()處理異常:
static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
int saved_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
........
if (pid == gSystemServerPid) {
kill(getpid(), SIGKILL);
}
}
變量gSystemServerPid表示SystemServer進程的pid,若SystemServer進程中止工做,那麼首先經過getpid()來獲取Zygote進程的pid,而後調用kill函數殺死它,即SystemServer中止工做以後,Zygote進程自殺,已達到Zygote與SystemServer生死與共的目的。
在Init進程的main()函數中有一個死循環,若是它的子進程Zygote中止工做,就會去重啓子進程,代碼以下:
int main(int argc,char** argv){
......
while(true){
if(!waiting_for_exec){
execute_one_command();
restart_processes();
//重啓死掉的service,若是zygote死掉了,就重啓Zygote。
.......
}
}
}
從這個過程可知,Init進程、Zygote進程、SystemServer進程緊密相連,任何一個都不能出問題。
SystemServer建立框架核心服務
當SystemServer啓動以後,就會進入main()方法,又在它的main()方法中調用run()方法。Android系統的核心服務AMS、WMS、PMS等就是在run()方法裏進行建立和初始化的,當它們建立以後,會經過ServiceManager的add_server()方法把它們加入到ServiceManager中統一管理。
public final class SystemServer {
.......
public static void main(String[] args) {
new SystemServer().run();
}
......
private void run() {
.....
Looper.prepareMainLooper();
//建立消息隊列
System.loadLibrary("android_servers");
//加載SystemServer須要的android_servers庫
createSystemContext();
//建立系統Context
......
startBootstrapServices();
startCoreServices();
startOtherServices();
//這三個方法是建立系統核心服務的實現
Looper.loop();
//進入消息循環,不止是應用程序有消息隊列,SystemServer也有
}
}
run()方法主要調用了三個重要的方法,在這三個方法中建立和初始化了重要的系統服務,如AMS、WMS、PMS等等。
APP應用程序進程
前面分析了Zygote如何啓動SystemServer子進程,接下來再分析Zygote如何啓動其餘子進程,也就是建立應用程序進程的過程,這個過程和建立SystemServer進程基本同樣。當點擊Launcher主界面的一個應用程序圖標時,若是這個應用程序還不曾啓動,就會啓動它。而判斷應用程序有沒有啓動和去啓動應用程序都由核心服務AMS來作,它的startProcessLocked()方法會真正地啓動應用程序子進程。
下面爲AMS的startProcessLocked()方法:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
......
ProcessStartResult startResult;
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, entryPointArgs);
}
.......
}
AMS的startProcessLocked()方法調用Process類的start()方法爲應用程序建立新的進程,這裏的參數entryPoint爲「android.app.ActivityThread」,它是傳進去的第一個參數,也就是程序初始化進程時要加載的主文件Java類。當應用進程啓動以後,會把這個類加載到進程,調用它的main()方法做爲應用程序進程的入口。
Process類的start()直接調用了ZygoteProcess類的start()方法,該start()方法有直接調用了ZygoteProcess類的startViaZygote()方法,下面看看該方法實現:
private Process.ProcessStartResult startViaZygote(final String processClass,final String niceName,final int uid, final int gid,final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String invokeWith,String[] extraArgs)throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
......
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
首先給它設置值,包括uid、gid等。這些值是應用程序在安裝時系統分配好的。接着調用openZygoteSocketIfNeeded()方法來連接「zygote」Socket,連接Socket成功以後,就會調用zygoteSendArgsAndGetResult()方法來進一步處理。
先來看看openZygoteSocketIfNeeded()方法:
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
.......
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);
}
.......
}
方法中的mSocket的值是「zygote」,經過connect()方法去連接「zygote」Socket。
接着看看zygoteSendArgsAndGetResult()方法:
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
........
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
.......
}
經過Socket寫入流writer把前面傳過來的那些參數寫進去,Socket即ZygoteServer類的runSelectLoop()方法監聽。寫入這些數據以後,ZygoteServer類的runSelectLoop()方法就能被監聽到。
看一下runSelectLoop()方法的關鍵實現代碼:
Runnable runSelectLoop(String abiList) {
.......
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
......
}
進入ZygoteConnection類的processOneCommand()方法後:
Runnable processOneCommand(ZygoteServer zygoteServer) {
........
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd);
........
}
以前啓動SystemServer進程的代碼有點類似。此處是經過Zygote.forkAndSpecialize()來fork新的應用進程,而啓動systemserver進程是經過Zygote.forkSystemServer()來fork SystemServer進程。這裏經過handleChildProc()方法處理,而以前是嗲偶用handleSystemServerProcess()來處理。經過fork新的應用程序進程以後,返回pid等於0就表示進入子進程,因而調用handleChildProc()方法進一步處理:
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd) {
........
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,null /* classLoader */);
.......
}
到此處,後面便和上面同樣的了,惟一不一樣的是,SystemServer進程啓動以後進入的是主類SystemServer.java的main()函數,而這裏應用程序啓動起來後進入的是主類是ActivityThread.java的main()函數。
至此,Zygote進程以及Zygote進程啓動SystemServer進程和啓動應用程序進程就分析完畢了,Zygote進程爲了啓動SystemServer和啓動應用程序進程主要作了兩件事,一是初始化Binder驅動用來進行進程間通訊,二是經過反射進入main()方法。