本文基于Android6.0.0系统
从这篇文章到后面的好几篇文章,会阅读从Android系统产生Zygote进程以后到我们点击应用图标启动应用进程这个过程中的源码,这个第一篇我们就来看看Zygote进程是如何被启动的.
我们都知道Android系统是基于Linux系统的,Linux中的所有进程都是有init进程fork出来的,那么Zygote进程也不例外,他也是有init进程fork出来的,这个我们在
\system\core\rootdir\init.zygote64.rc 文件中就可以看得到.
值得一提的是,在之前的Android源码中init文件只有一个,现在的话谷歌程序员将init中的一些操作进行了剥离,如执行创建zygote进程的代码就分为了如下好几个版本,这个应该是针对不同系统所做出的调整.
1)我们以init.zygote32.rc文件为例看看他里面都做了什么
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
这种.rc中的脚本命令的含义我们都可以在\system\core\init\readme.txt
文件中找到他的含义 例如service:
Services
--------
Services are programs which init launches and (optionally) restarts
when they exit. Services take the form of:
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
1.第一句命令中的意义是 要创建出一个名叫 zygote 的进程,这个进程所要执行的程序就在 /system/bin/app_process
目录下, -Xzygote /system/bin --zygote --start-system-server
是要传入到app_process
程序中的参数
2.第三句的作用是要在上面创建的 zygote
进程中 启动一个名叫 zygote 的socket,这个socket就是我们后面用作ActivityManagerService进程和这个zygote进程通信的,主要是请求zygote进程fork出一个新的应用程序进程
3.后面的这几句onRestart...命令都是在zygote进程重启时需要执行的命令
2)后面我们确定到/system/bin/app_process
对应的文件就是 \frameworks\base\cmds\app_process\app_main.cpp
文件,我们来看看app_main.cpp中都做了什么.
int main(int argc, char* const argv[])
{
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
if (errno != EINVAL) {
LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
return 12;
}
}
//创建AppRuntime 变量
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
argc--;
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.addOption(strdup(argv[i]));
}
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
//我们传入和参数包含 "--zygote" 和 "--start-system-server" 所以 zygote 和 startSystemServer 都会被置为true
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} 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;
}
}
Vector<String8> args;
if (!className.isEmpty()) {
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) {
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;
}
}
1.首先我们要明确一点的是,我们给main函数传递过来的参数中是 -Xzygote /system/bin --zygote --start-system-server.
2.因为参数中包含了 --zygote所以他最后会走 runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
这句代码,其实main函数中主要的工作也就是启动创建AppRuntime 这个变量,而且在最后也执行了AppRuntime的start()方法.
3)下面我们在看看AppRuntime中都做了些什么,AppRuntime也是类位于\frameworks\base\cmds\app_process\app_main.cpp
文件中,我们可以发现他是继承自AndroidRuntime的,而且在他里面没有找到start()方法,所以就到他的父类AndroidRuntime中找
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength)
: AndroidRuntime(argBlockStart, argBlockLength)
, mClass(NULL){
}
.....
}
4)AndroidRuntime位于 \frameworks\base\core\jni\AndroidRuntime.cpp
中,下面的代码就是start()方法,从注释中看,就可以看出来这个方法主要是负责启动Android Runtime的,而且也会牵扯到调用传入className 的 main 方法去启动虚拟机
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
static const String8 startSystemServer("start-system-server");
/*
* 'startSystemServer == true' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//启动虚拟机
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
//注册JNI方法
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.
*/
//将现有的参数转换成ZygoteInit中main方法需要的String 数组
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. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
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 {
//调用ZygoteInit的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");
}
1.我们先确认一下,传过来的参数是runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
这里的第三个参数zygote经过我们的分析应该是 true
2.这个start()方法主要做了三件事情,
1)调用startVm()方法启动虚拟机
2)调用startReg()注册了Android的JNI方法
3)调用 env->CallStaticVoidMethod(startClass, startMeth, strArray);方法来调用ZygoteInit的main方法来启动SystemServer进程
5)下面我们就来看看ZygoteInit文件的main方法,该文件位于\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
try {
//启动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++) {
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.");
}
//创建一个Socket用来和ActivityManagerService进行通信
registerZygoteSocket(socketName);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//加载类,加载资源,加载OpenGL等
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);
//进行SystemServer进程的创建(fork)
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
Log.i(TAG, "Accepting command socket connections");
//开启无限循环等待ActivityMangerService发送通知去fork一个新的应用程序进程
runSelectLoop(abiList);
//关闭socket
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
1.首先我们在AndroidRuntime中给ZygoteInit中传入的参数会包含"start-system-server"所以**startSystemServer **会被置为true
2.调用 registerZygoteSocket(socketName);来创建一个Socket用来和ActivityManagerService进行通信
/**
* Registers a server socket for zygote command connections
*
* @throws RuntimeException when open fails
*/
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.调用preload()方法去加载一些常用的类,图片,颜色.
static void preload() {
Log.d(TAG, "begin preload");
//加载Android中常用的类
preloadClasses();
//加载Android中常用的资源,图片等
preloadResources();
//加载openGL
preloadOpenGL();
//加载Android中需要的一些类库,如android,jnigraphics,compiler_rt等
preloadSharedLibraries();
//初始化Hyphenator(用来显示文字)
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
//初始化WebView(在Zygote进程中初始化是为了达到内存共享的目的)
WebViewFactory.prepareWebViewInZygote();
Log.d(TAG, "end preload");
}
4.调用 startSystemServer(abiList, socketName);来进行fork一个新的进程用来启动SystemServer组件,这也就是我们说的SystemServer进程
/**
* Prepare the arguments and fork for the system server process.
*/
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会等于0
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;
}
- 调用 runSelectLoop();开启无限循环等待ActivityMangerService发送通知去fork一个新的应用程序进程
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
6.调用RuntimeInit.enableDdms();
来启动DDMS
6)在上面第4条我们说过在创建SystemServer进程的时候pid会返回0,那么后续代码自然就会执行handleSystemServerProcess(parsedArgs);我们一起来看看这个方法中都干了什么
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
//因为新创建的进程是在Zygote进程中启动的,所以该进程也会继承那个Socket,这里先将这个socket关闭掉
closeServerSocket();
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
}
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
1.通过分析我们可以看出来这个方法是完成fork完SystemServer进程后的其他工作
2.这个方法中最关键的就是** RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);**这个方法主要是去完成SystemServer进程的启动
7)下面我们看看RuntimeInit.zygoteInit()方法中都干了什么,RuntimeInit文件位于
\android-6.0.0_r1\frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
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");
//将 System.out 和 System.err 定向到Android日志中
redirectLogStreams();
commonInit();
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
1.首先我们明确第二个参数中包含了com.android.server.SystemServer
这个全类名
2.调用redirectLogStreams();方法将 System.out 和 System.err 定向到Android日志中
4.调用 commonInit();方法做时间,AndroidConfig的初始化
5.调用nativeZygoteInit();这个native方法去初始化一个Binder用来做进程间通信
6.在 applicationInit(targetSdkVersion, argv, classLoader);中调用 invokeStaticMain(args.startClass, args.startArgs, classLoader);这个方法来调用SystemServer这个类的main方法
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 {
//调用main方法
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);
}
8)下面我们就看看nativeZygoteInit()方法中做了什么
private static final native void nativeZygoteInit();
我们可以看到他是一个native方法,它对应的实现方法是在 android-6.0.0_r1\frameworks\base\core\jni\AndroidRuntime.cpp
文件中
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime其实就是AndroidRuntime本身
static AndroidRuntime* gCurRuntime = NULL;
然后再去找onZygoteInit()方法,但是我们在AndroidRuntime.cpp文件中没有找到,我们再去AndroidRuntime.h这个头文件去找,发现AndroidRuntime是一个虚拟类,,所以我们需要在他的子类中找实现了的onZygoteInit()方法.
我们知道AppRuntime继承了AndroidRuntime所以我们在APPRuntime中看看,他的文件对应在android-6.0.0_r1\frameworks\base\cmds\app_process\app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
然后调用了ProcessState的startThreadPool()方法,ProcessState类位于android-6.0.0_r1\frameworks\native\libs\binder\ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
这个方法主要是启动一个线程池,该线程池中的线程主要是负责和binder驱动程序进行交互的,ProcessState是Binder进程间通信的一个基础组件,这里我们就不在深究了,后面我们会仔细分析关于Android IPC的问题这里我们只需要知道nativeZygoteInit()方法就初始化了一个线程池用于和Binder基础组件,这个方法执行完后这个进程的Binder进程间通信基础就准备好了.
9)下面我们看看SystemServer中的main方法都干了什么,SystemServer位于android-6.0.0_r1\frameworks\base\services\java\com\android\server\SystemServer.java
中
public static void main(String[] args) {
new SystemServer().run();
}
mian方法执行完毕后SystemServer进程就启动了这个会在下面
SystemServer进程启动源码阅读 中分析
10)最后我们在回到5.5中,里面提到会调用ZygoteInit.runSelectLoop()
方法开启一个无限循环,等待ActivityManagerService来连接这个socket然后调用ZygoteConnection.runOnce函数来创建新的应用程序进程,后面我们学习到Android启动应用程序的时候会仔细分析.
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*
* @throws MethodAndArgsCaller in a child process when a main() should
* be executed.
*/
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
11)到这里Zygote进程的启动就完成了,下面是这个流程的时序图
值得注意的点
1.Android中的进程间通信一般是使用Binder的但是有特例就是zygote进程和SystemServer进程间的通信是使用Socket进行的
2.DDMS ;Android中常用的类和资源 ;OpenGL; android,jnigraphics,compiler_rt类库; WebView都是在ZygoteInit类中的main方法中加载的,其实WebView选择在Zygote进程中初始化是为了达到内存共享的目的
3.系统启动init进程的时候在init进程中会启动一个Zygote进程,Zygote进程负责Android程序框架和其他进程的启动
4.Zygote进程首先会启动一个SystemServer进程,该进程用于启动Android程序中的各种服务,如PackageManagerService等
5.当我们需要新建一个应用程序进程时ActivityManagerService会通过socket进程间通信,通知Zygote去新建一个进程.
6.在AndroidRuntime的main方法中启动了虚拟机,注册了JNI方法
7.Zygote进程在Linux解析init.zygote32.rc中的 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
这句代码的饿时候就已经创建了,后面执行的/system/bin/app_process
中的代码都是在该进程中执行的
参考文章
http://blog.csdn.net/luoshengyang/article/details/6768304
http://blog.csdn.net/qq_23547831/article/details/51104873