从上一篇init的启动可以看到,zygote由init进程解析init.zygoteXXX.rc文件,然后fork进程,并为zygote进程创建了/dev/socket/zygote的socket接口,然后创建zygote进程,执行/system/bin/app_process,传入参数:-Xzygote /system/bin –zygote –start-system-server

本文,我们看下app_process干了些什么事情

仍然是AndroidStudio查找源码的流程:

  1. Ctrl + Shift + F 全局查找字符串 := app_process
  2. 找到Android.mk文件:frameworks/base/cmds/app_process/Android.mk
  3. 对应的LOCAL_SRC_FILES:= \app_main.cpp,因此app_process的源码位于frameworks/base/cmds/app_process/app_main.cpp中

开始阅读:app_main.cpp -> main()方法

记住,在init在执行的时候,入参是:-Xzygote /system/bin –zygote –start-system-server,解析得到的args = {“-Xzygote” “/system/bin”,”-zygote“, ”-start-system-server“},携带这些参数,我们来看下main方法的执行情况

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//使用argv[0]参数进行
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
// Process command line arguments
// ignore argv[0], 忽略argv[0]参数
//argc-1 = 3
argc--;
//argv++,即数组头指针后移一个位置
argv++;
...
int i;
for (i = 0; i < argc; i++) {
//如果参数不是以'-'开头,直接跳出循环
if (argv[i][0] != '-') {
break;
}
//如果参数第二个字符为'-'并且第三个字符为截止字符,则忽略,并跳出循环
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
//为runtime添加参数
runtime.addOption(strdup(argv[i]));
}
//因此,因为此前的argv++,故而argv[0]="/syste/bin",故而跳出上述循环,此时i = 0
...
//++i,跳过了第一个参数/system/bin,即跳过父目录参数
++i; // Skip unused "parent dir" argument.
//继续执行
while (i < argc) {
const char* arg = argv[i++];
//i = 1, argv[1] = "--zygote", 然后i++
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
//i = 1, argv[2] = "-start-system-server", 然后i++=3 = argc,跳出循环
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
//因此上述while做了几个事情:
//1. zygote = true;
//2. niceName = ZYGOTE_NICE_NAME; // zygote或者zygote64
//3. startSystemServer = true;
//下面代码的注释已经比较清除了,args是runtime.start()要传入的参数之一
Vector<String8> args;
if (!className.isEmpty()) {
// We're not in zygote mode, the only argument we need to pass
// to RuntimeInit is the application argument.
//
// The Remainder of args get passed to startup class main(). Make
// copies of them before we overwrite them with the process name.
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
} else {
// We're in zygote mode.
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
//设置进程名称
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string());
set_process_name(niceName.string());
}
if (zygote) {
//进入AppRuntime.start方法
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
return 10;
}

AppRuntime->start()方法

AppRuntime的定义在app_main.cpp中,继承于AndroidRuntime类,类文件位于frameworks/base/core/jni/AndroidRuntime.cpp,头文件位于frameworks/base/include/android_runtime/AndroidRuntime.h

而AppRuntime主要重写了几个方法:

  • onVmCreated
  • onStarted
  • onZygoteInit
  • onExit
  • 并定义了方法setClassNameAndArgs
  • 新增了几个成员:String8 mClassName, Vector mArgs, jclass mClass;

start方法位于AndroidRuntime中定义,我们来看看:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
//startSystemServer = "start-system-server"
static const String8 startSystemServer("start-system-server");
...
//将rootDir设置为"/system"
const char* rootDir = getenv("ANDROID_ROOT");
//1. 启动虚拟机
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env; //虚拟机环境指针
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//注册jni函数
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
assert(optionsStr != NULL);
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
/*
* Start VM.
* 注意以下两点
* 1. This thread becomes the main thread of the VM,
* 2. and will not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
//找到class字节码实例:com.android.internal.os.ZygoteInit.class
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} 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);
/* keep going */
} else {
//调用main函数,进入ZygoteInit.main()中,直到main函数退出(此时虚拟机也会退出)
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
//未正常退出
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
//虚拟机退出
ALOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
ALOGW("Warning: VM did not shut down cleanly\n");
}

其中:

  • startVm(): 一系列的虚拟机环境参数配置,最终调用JNI_CreateJavaVM初始化虚拟机,如果方法调用成功,则虚拟机准备完毕,这部分是dalvikVm的知识,以后再研究
  • startReg(): 主要通过register_jni_procs来注册jni函数,如register_com_android_internal_os_RuntimeInit、register_android_opengljni…等等jni library

启动虚拟机之后,进入Java世界: ZygoteInit.main()

还是来看代码,

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
try {
//调试相关
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
/开启ddms
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++) {
//是否需要启动systemserver: zygote进程启动时候,true
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
//是否包含abilist,zygote进程,true
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
//是否包含socketname,zygote进程,true
} 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.");
}
//注册zygote的socket服务端接口
registerZygoteSocket(socketName);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//预加载:类、资源、opengl已经共享库等等,这样在fork一个新的进程的时,就不再需要重新加载这些资源
//而由于linux的fork机制,这些预加载的资源,除非有修改需求,否则都共享父进程的同一个资源
preload();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
//进行依次gc回收
gcAndFinalize();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
ZygoteHooks.stopZygoteNoThreadCreation();
//启动SystemServer进程
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
Log.i(TAG, "Accepting command socket connections");
//进入select loop循环
runSelectLoop(abiList);
//关闭服务端server socket
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
//caller.run()
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}

小结,ZygoteInit.main()主要做了几件事情:

  1. registerZygoteSocket,注册zygote的socket服务,等待其他client的请求
  2. startSystemServer开启systemserver进程,这是java世界的基石:包含了众多的服务,如AMS, WMS,IMS等等
  3. 调用runSelectLoop,进入无限循环,等待client请求,来创建进程,每创建一个进程,在子进程中都会抛出异常MethodAndArgsCaller,从而子进程中的代码会运行到caller.run()方法中去

1. registerZygoteSocket()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//入参是"zygote"
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
//由于zygote进程创建的时候,会创建名为zygote的socket节点的fd,并将节点设置到环境变量ANDROID_SOCKET_zygote中去
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);
//创建socket的server端
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}

2. startSystemServer()

另外开一篇文章来写吧,这里我们记住,system_server进程,由zygote进程fork出来,然后在创建的虚拟机中执行SystemServer.main()方法

3. runSelectLoop()

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
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
//fds和peers一一对应
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//服务端的fd对应着null值
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
//进入无限循环, 采用 多路复用机制 + socket配合 进行阻塞等待client的请求
while (true) {
//监听所有的fd的POLLIN请求,即监听socket可读事件
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
////pollFds[0]即为fds[0],也就是sServerSocket.fd
//1. 一开始,zygote刚启动的时候,这个fds只有sServerSocket.fd一个元素
//2. 当有新的client连接sServerSocket时候,就会触发sServerSocket.fd的POLLIN事件
//3. 从而导致后面for循环中,i==0成立,然后往peers中新加一个peers,以及往fds列表中添加客户端的fd
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
//开始poll系统调用,监听多个文件的POLLIN事件,阻塞。 当有事件来临时,继续往下执行
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
//遍历所有监控的fd,如果不存在POLLIN事件,则continue跳过该fd,否则执行后面的操作
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
//i=0,说明是zygote进程的server端的socket,因此调用socket.accept,获取与客户端的链接,从而拿到fd
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
//添加到fds列表
fds.add(newPeer.getFileDesciptor());
} else {
//处理客户端链接
boolean done = peers.get(i).runOnce();
//处理完毕,将fd和peers删除
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
  1. 开启sServerSocket,等待客户端请求
  2. 客户端请求来临,调用ZygoteConnection.runOnce()处理请求

调用ZygoteConnection.runOnce()处理请求

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
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
...
//读取client端入参列表
args = readArgumentList();
...
int pid = -1;
...
//fork进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// should never get here, the child is expected to either
// throw ZygoteInit.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}

handleChildProc 与 handleParentProc

首先来看 handleChildProc,即zygote进程fork出来的子进程执行的方法

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
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
/**
* By the time we get here, the native code has closed the two actual Zygote
* socket connections, and substituted /dev/null in their place. The LocalSocket
* objects still need to be closed properly.
*/
//子进程不再需要处理socket请求,因此关掉两端
closeSocket();
ZygoteInit.closeServerSocket();
...
//子进程名字的设置
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//如果定义了invokeWith参数,则采用 /system/bin/sh这种execShell的方式执行command
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
//否则调用zygoteInit,执行初始化
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}

RuntimeInit.zygoteInit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
//log重定向
redirectLogStreams();
//通用初始化:default UncaughtExceptionHandler、TimeZone、userAgent、NetworkManagementSocketTagger、trace等等
commonInit();
//调用frameworks/base/core/jni/AndroidRuntime.cpp
//最终调用gCurRuntime->onZygoteInit,其中gCurRuntime是在zygote进程执行app_main.cpp->main()时创建的,
//而新fork出来的子进程都是基于zygote进程的,因此也会存在该实例
//调用AndroidRuntime.onZygoteInit()方法,与binder交互
nativeZygoteInit();
//应用初始化
applicationInit(targetSdkVersion, argv, classLoader);
}

startThreadPool方法的调用, 参考链接:http://blog.csdn.net/ganyue803/article/details/41484849

1
2
3
4
5
6
7
8
virtual void onZygoteInit()
{
//binder交互
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
//开启主线程,并与binder 最终talkWithDriver()
proc->startThreadPool();
}

RuntimeInit.applicationInit

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
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

RuntimeInit.invokeStaticMain

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
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
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) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

最终,子进程中,调用invokeStaticMain,抛出ZygoteInit.MethodAndArgsCaller异常,从而跳转到ZygoteInit.main()方法的exception处理中,调用caller.run();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}

即,调用ZygoteInit.MethodAndArgsCaller(m, argv)这个main方法,并传参argv

PS: 为采用抛出异常这种方式来跳转呢?

  1. java中,线程的方法栈中,包含了一个个的栈帧,每个栈帧都是一个方法
  2. 抛出异常的时候,java会依次将方法栈帧出栈,寻找能够处理异常的栈帧
  3. 因此,zygote fork出来的子进程,最终会将ZygoteInit.main()方法栈帧上面的栈帧都清空掉
  4. 从而是的子进程都是从ZygoteInit.mian()方法起栈的

而对于父进程,也就是我们的zygote进程, 来看看handleParentProc

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 boolean handleParentProc(int pid,
FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {
if (pid > 0) {
setChildPgid(pid);
}
if (descriptors != null) {
for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
}
boolean usingWrapper = false;
if (pipeFd != null && pid > 0) {
DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));
int innerPid = -1;
try {
innerPid = is.readInt();
} catch (IOException ex) {
Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
} finally {
try {
is.close();
} catch (IOException ex) {
}
}
// Ensure that the pid reported by the wrapped process is either the
// child process that we forked, or a descendant of it.
if (innerPid > 0) {
int parentPid = innerPid;
while (parentPid > 0 && parentPid != pid) {
parentPid = Process.getParentPid(parentPid);
}
if (parentPid > 0) {
Log.i(TAG, "Wrapped process has pid " + innerPid);
pid = innerPid;
usingWrapper = true;
} else {
Log.w(TAG, "Wrapped process reported a pid that is not a child of "
+ "the process that we forked: childPid=" + pid
+ " innerPid=" + innerPid);
}
}
}
try {
mSocketOutStream.writeInt(pid);
mSocketOutStream.writeBoolean(usingWrapper);
} catch (IOException ex) {
Log.e(TAG, "Error writing to command socket", ex);
return true;
}
return false;
}

主要做了一些fork清理工作,并没有抛出异常,因此还是在runSelectLoop这个循环中继续往下执行

完结

至此,整个zygote进程的启动流程执行完毕,主要做了以下事情:

  1. app_main.cpp -> main(), AppRuntime的初始化:创建虚拟机、注册jni函数
  2. 执行com.android.internal.os.ZygoteInit -> main()函数
  3. registerZygoteSocket注册服务端sServerSocket
  4. preload: 基本资源、库的加载
  5. 如果需要启动systemserver,则启动systemserver进程
  6. runSelectLoop: 进入无限循环,采用poll + socket的机制,等待client端的请求
    6.1 请求过来,fork进程,并在新的进程中运行class的main方法
    6.2 父进程做完清理工作,继续在无限循环中执行

参考链接:
http://blog.csdn.net/yaowei514473839/article/details/53022493
http://blog.csdn.net/yaowei514473839/article/details/53045285