Zygote进程源码分析
由app_process运行ZygoteInit class
zygote由java编写而成,不能直接由init进程启动运行。若想执行zygote类,必须先创建虚拟机,然后在虚拟机上运行ZygoteInit类。执行这一任务的就是app_process程序。 下面我们开始分析zygote进程的启动流程: /system/core/rootdir/init.rc
可以看到init.rc中有如下导包
代码语言:javascript复制import /init.$(ro.zygote).rc
如果是64位系统,$(ro.zygote)的值为"zygote64" /system/core/rootdir/init.zygote64.rc
代码语言:javascript复制service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
app_process64程序的main函数入口如下: frameworks/base/cmds/app_process/app_main.cpp
代码语言:javascript复制int main(int argc, char* const argv[])
{
......
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
......
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
......
while (i < argc) {
const char* arg = argv[i ];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
}
......
}
......
if (zygote) {
//zygote进程
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
//普通java进程
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
}
如果是zygote进程就走ZygoteInit代码,如果是普通java进程就走RuntimeInit代码,例如常用的am命令,/system/bin/am实际上是一个shell脚本,查看里面的代码可知是通过app_process来启动普通java进程,然后和AMS进行通信。
这里AppRuntime继承自AndroidRuntime,所以看到AndroidRuntime的start方法
frameworks/base/core/jni/AndroidRuntime.cpp
代码语言:javascript复制//AppRuntime继承自AndroidRuntime
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* start the virtual machine */
JniInvocation jni_invocation;
// ① 加载指定的虚拟机的库(art或者dalvik)
jni_invocation.Init(NULL);
JNIEnv* env;
// ② 创建java虚拟机
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
// ③ 注册JNI函数
if (startReg(env) < 0) {
return;
}
......
// ④ 正式进入java的世界,调用ZygoteInit.java的main方法
jclass startClass = env->FindClass(slashClassName);
......
jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");
......
env->CallStaticVoidMethod(startClass, startMeth, strArray);
......
}
①: 加载虚拟机的库(art或者dalvik),并且函数指针指向库对应的函数(如:JNI_CreateJavaVM函数) libnativehelper/JniInvocation.cpp
代码语言:javascript复制bool JniInvocation::Init(const char* library) {
//获取要加载库的名称
library = GetLibrary(library, buffer);
//动态加载对应的虚拟机库
handle_ = dlopen(library, RTLD_NOW);
......
//JNI_CreateJavaVM_函数指针指向虚拟机库中的JNI_CreateJavaVM函数
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return false;
}
.......
return true;
}
GetLibraray()函数获取动态库的名称(libart.so或者libdalvik .so),dlopen()函数动态加载虚拟机库,RTLD_NOW表示返回之前立即链接所有未定位的符号,FindSysmbol()函数指针指向对应的函数。
函数说明: dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,dlerror返回出现的错误,dlsym通过句柄和连接符名称获取函数名或者变量名,dlclose来卸载打开的库。 dlopen打开模式如下:
RTLD_LAZY 暂缓决定,等有需要时再解出符号 RTLD_NOW 立即决定,返回前解除所有未决定的符号。
dlclose(handle);关闭动态链接库
代码语言:javascript复制bool JniInvocation::FindSymbol(void** pointer, const char* symbol) {
*pointer = dlsym(handle_, symbol);
if (*pointer == NULL) {
ALOGE("Failed to find symbol %s: %sn", symbol, dlerror());
dlclose(handle_);
handle_ = NULL;
return false;
}
return true;
}
libnativehelper/JniInvocation.cpp
代码语言:javascript复制static const char* kLibrarySystemProperty = "persist.sys.dalvik.vm.lib.2";
static const char* kDebuggableSystemProperty = "ro.debuggable";
static const char* kDebuggableFallback = "0"; // Not debuggable.
static const char* kLibraryFallback = "libart.so";
const char* JniInvocation::GetLibrary(const char* library, char* buffer, bool (*is_debuggable)(),
int (*get_library_system_property)(char* buffer)) {
#ifdef __ANDROID__
const char* default_library;
//如果不是debug设备,library的值为"libart.so"
if (!is_debuggable()) {
// Not a debuggable build.
// Do not allow arbitrary library. Ignore the library parameter. This
// will also ignore the default library, but initialize to fallback
// for cleanliness.
library = kLibraryFallback;
default_library = kLibraryFallback;
} else {
// Debuggable build.
// Accept the library parameter. For the case it is NULL, load the default
// library from the system property.
if (buffer != NULL) {
if (get_library_system_property(buffer) > 0) {
default_library = buffer;
} else {
default_library = kLibraryFallback;
}
} else {
// No buffer given, just use default fallback.
default_library = kLibraryFallback;
}
}
#else
UNUSED(buffer);
UNUSED(is_debuggable);
UNUSED(get_library_system_property);
const char* default_library = kLibraryFallback;
#endif
if (library == NULL) {
library = default_library;
}
return library;
}
代码语言:javascript复制bool IsDebuggable() {
#ifdef __ANDROID__
char debuggable[PROP_VALUE_MAX] = {0};
__system_property_get("ro.debuggable", debuggable);
return strcmp(debuggable, "1") == 0;
#else
return false;
#endif
}
②: 创建java虚拟机 frameworks/base/core/jni/AndroidRuntime.cpp
代码语言:javascript复制int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
JavaVMInitArgs initArgs;
......
initArgs.version = JNI_VERSION_1_4;
initArgs.options = mOptions.editArray();
initArgs.nOptions = mOptions.size();
initArgs.ignoreUnrecognized = JNI_FALSE;
......
//创建java虚拟机
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failedn");
return -1;
}
return 0;
}
JNI_CreateJavaVM()是JniInvocation.cpp中的函数,会调用到①中所说的JNI_CreateJavaVM_()函数指针,最后调用到相应虚拟机动态库中的JNI_CreateJavaVM()函数,创建对应的虚拟机。initArgs表示传入的虚拟机参数。
代码语言:javascript复制C/C 预处理指令,常见的预处理指令如下:
#空指令,无任何效果
#include包含一个源代码文件
#define定义宏
#undef取消已定义的宏
#if如果给定条件为真,则编译下面代码
#ifdef如果宏已经定义,则编译下面代码
#ifndef如果宏没有定义,则编译下面代码
#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个#if……#else条件编译块
#error停止编译并显示错误信息
③: 注册JNI本地函数 我们先来熟悉一下几个数据结构: frameworks/base/core/jni/AndroidRuntime.cpp
代码语言:javascript复制#define REG_JNI(name) { name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
};
......
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
......
};
gRegJNI是RegJNIRec结构体数组,然后数组通过REG_JNI宏定义初始化。例如gRegJNI第一个元素的初始化,等同于:
代码语言:javascript复制gRegJNI[0] = {register_com_android_internal_os_RuntimeInit};
那么gRegJNI[0]中RegJNIRec结构体的mProc函数指针就指向上面的函数register_com_android_internal_os_RuntimeInit,数组中的其它元素也同理。下面我们继续分析JNI本地函数的注册。
frameworks/base/core/jni/AndroidRuntime.cpp
代码语言:javascript复制int AndroidRuntime::startReg(JNIEnv* env)
{
......
//注册JNI本地函数,将gRegJNI数组传入
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
return -1;
}
......
return 0;
}
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
//遍历执行gRegJNI数组中元素的mProc函数
//(mProc是函数指针,数组初始化的时候已经指向指定的函数)
for (size_t i = 0; i < count; i ) {
if (array[i].mProc(env) < 0) {
return -1;
}
}
return 0;
}
startReg会调用register_jni_procs遍历调用gRegJNI数组中的mProc函数,以第一个元素为例,gRegJNI[0].mProc(env)由上面的分析可知调用的实际是register_com_android_internal_os_RuntimeInit(env)函数。
frameworks/base/core/jni/AndroidRuntime.cpp
代码语言:javascript复制int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeFinishInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
......
};
//最后会调用到(*env)->RegisterNative()注册
return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
methods, NELEM(methods));
}
用上面的代码可知,nativeFinishInit函数映射了com_android_internal_os_RuntimeInit_nativeFinishInit函数,当java调用nativeFinishInit函数时,实际会调用到c/c 中的com_android_internal_os_RuntimeInit_nativeFinishInit函数。有读者可能会问,java调用jni函数时,虚拟机会自动映射,为什么要自己映射呢?如果jni函数比较少,这么做确实可行,但是我们可以看到gRegJNI数组是很庞大的,需要映射的函数也很多,如果全部交给虚拟机映射,会大大降低虚拟机的执行性能,所以我们提前注册JNI函数,虚拟机就可以直接找到对应的函数进行调用。
④: 通过反射调用ZygoteInit.java的main函数,正式进入java的世界。env->FindClass获取ZygoteInit类的类型,env->GetStaticMethodID获取函数main的函数id,env->CallStaticVoidMethod调用ZygoteInit.java的静态函数main。
ZygoteInit类的功能
至此,我们已经创建好了虚拟机,并且将ZygoteInit类装载到了虚拟机。接下来,ZygoteInit类将会被运行,那么ZygoteInit类具体有哪些功能呢?大致概括为如下几点:
代码语言:javascript复制绑定套接字,用来接收新Android应用程序运行请求
预加载Android Application Framework 使用的类与资源
启动并运行SystemServer
处理新Android应用程序运行请求
ZygoteInit的main函数: frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
代码语言:javascript复制public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
......
try{
boolean startSystemServer = false;
String socketName = "zygote";//套接字默认名称zygote
for (int i = 1; i < argv.length; i ) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
}
......
}
// ① 绑定/dev/socket/zygote套接字,用来接收Android应用程序运行请求
zygoteServer.registerServerSocketFromEnv(socketName);
......
if (!enableLazyPreload) {
......
// ② 预加载类与资源
preload(bootTimingsTraceLog);
......
}
......
if (startSystemServer) {
// ③ fork出system_server子进程
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// ③ {@code r == null}表示是父进程(zygote),{@code r != null}在子进程(system_server)
if (r != null) {
// ③ 如果是子进程(system_server)就执行run()方法,并返回,父进程(zygote)就继续往下执行
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// ④ 这轮询会在zygote进程中无限循环,而fork出的子进程(Android应用进程)会退出来
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
//system_server进程和android应用进程会关闭socket,zygote仍然在runSelectLoop中轮询监听socket
zygoteServer.closeServerSocket();
}
// ④ Android应用进程会走到这儿,执行相应的命令
if (caller != null) {
caller.run();
}
}
①: 绑定套接字,用来接收运行Android应用运行请求 frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
代码语言:javascript复制void registerServerSocketFromEnv(String socketName) {
if (mServerSocket == null) {
int fileDesc;
//fullSocketName为“ANDROID_SOCKET_zygote”
final String fullSocketName = ANDROID_SOCKET_PREFIX socketName;
try {
//获取ANDROID_SOCKET_zygote的坏境变量(即为/dev/socket/zygote的文件描述符的值)
//是init进程在启动zygote进程时保存到环境变量中的
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName " unset or invalid", ex);
}
try {
//绑定socket,在后面用来接收Android应用启动请求
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);
mCloseSocketFd = true;
} catch (IOException ex) {
......
}
}
}
②: 预加载类和资源,后面从zygote进程fork出的应用进程可以直接共享,加快应用进程启动速度。 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
代码语言:javascript复制static void preload(TimingsTraceLog bootTimingsTraceLog) {
......
preloadClasses();
......
preloadResources();
......
nativePreloadAppProcessHALs();
......
preloadOpenGL();
preloadSharedLibraries();
preloadTextResources();
.......
}
③: forkSystemServer fork出system_server子进程,并返回可以调用SystemServer中main方法的Runnable r,并执行对应的run方法,而父进程zygote则继续往下执行runSelectLoop,监听Android应用运行执行请求。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
代码语言:javascript复制private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
......
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000", //用户id
"--setgid=1000", //组id
......
"--nice-name=system_server",
......
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
......
//fork出system_server子进程,并且设置对应的参数
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//子进程(system_server)
if (pid == 0) {
......
//所以返回的r不为null,直接执行r.run
return handleSystemServerProcess(parsedArgs);
}
//父进程(zygote),返回的是null,继续往下执行
return null;
}
ZygoteInit的forkSystemServer方法会调用Zygote的forkSystemServer方法,如果是子进程(system_server)就返回handleSystemServerProcess(),父进程(zygote)就返回null。 frameworks/base/core/java/com/android/internal/os/Zygote.java
代码语言:javascript复制public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
......
int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags,
rlimits, permittedCapabilities, effectiveCapabilities);
......
return pid;
}
调用nativeForkSystemServer fork出子进程,nativeForkSystemServer是本地方法,在前面已经通过startReg方法中的register_com_android_internal_os_Zygote将nativeForkSystemServer方法映射到com_android_internal_os_Zygote_nativeForkSystemServer方法上
fork出子进程之后,子进程就开始调用handleSystemServerProcess()方法 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
代码语言:javascript复制private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
......
//从环境变量SYSTEMSERVERCLASSPATH获取到SystemServer类文件相应jar包的路径
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
//对相应的jar包做dex优化处理
performSystemServerDexOpt(systemServerClasspath);
......
}
......
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建类加载器classloader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
先从SYSTEMSERVERCLASSPATH环境中获取到SystemServer的classpath,然后使用performSystemServerDexOpt对classpath对应的jar包做dex优化处理。然后创建对应的classloader,后续用来加载SystemServer类,ZygoteInit.zygoteInit()继续往下执行: frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
代码语言:javascript复制public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
......
//将标准输出流和标准错误流重定向到Android log中
RuntimeInit.redirectLogStreams();
......
//本地方法,startReg映射,主要是开启ProcessState线程池,用来进行binder通信
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
redirectLogStreams会将标准输入,错误流重定位到Android log中,nativeZygoteInit JNI函数(startReg映射)会开启ProcessState线程池,用来进行binder通信。
继续往下执行RuntimeInit.applicationInit(): frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
代码语言:javascript复制protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {
......
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
继续往下执行:
代码语言:javascript复制/**
* Invokes a static "main(argv[]) method on class "className".
* Converts various failing exceptions into RuntimeExceptions, with
* the assumption that they will then cause the VM instance to exit.
*
* @param className Fully-qualified class name
* @param argv Argument vector for main()
* @param classLoader the classLoader to load {@className} with
*/
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {
Class<?> cl;
......
//获取到SystemServer的类类型
cl = Class.forName(className, true, classLoader);
......
Method m;
try {
//获取到main方法的方法id
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
......
} catch (SecurityException ex) {
......
}
//这个就是③中forkSystemServer的返回值r
return new MethodAndArgsCaller(m, argv);
}
findStaicMain获取到SystemServer的类类型,并且获取到SystemServer中的main方法的方法id。然后new MethodAndArgsCaller(m,argv)就是③中forkSystemServer的返回值r,让我们看看r.run做了一些什么。 frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
代码语言:javascript复制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静态方法
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
......
} catch (InvocationTargetException ex) {
......
}
}
}
由上可知,就是通过反射执行SystemServer类的main方法。众所周知,system_server进程注册和运行着AMS、PMS、PKMS等核心系统服务
④: zygoteServer.runSelectLoop()这轮询会在zygote进程中无限循环,而fork出的子进程(Android应用进程)会退出并继续往下执行
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
代码语言:javascript复制//开启zygote进程轮询监听。接收新的socket连接(会创建新的ZygoteConnection)
//并且从这些链接中中读取命令,并且执行
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.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) {//如果是新的socket链接请求(建立新连接)
//新建ZygoteConnection链接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
//添加到链接数组中
peers.add(newPeer);
//添加到文件描述符数组中
fds.add(newPeer.getFileDesciptor());
} else {//如果是之前已经建立的socket链接(在已有连接上)
try {
//获取对应的ZygoteConnection
ZygoteConnection connection = peers.get(i);
//会执行ZygoteConnection发送过来的命令
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {//子进程走这儿
......
//退出,command就是④中的caller
return command;
} else {//父进程走这儿,上面是while无限循环,zygote进程永远不会退出
......
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
......
} finally {
mIsForkChild = false;
}
}
}
}
}
上面的流程概括来说,就是会轮询/dev/socket/zygote的socket,如果有新的链接,就新建ZygoteConnection,并将对应的socket fd添加到fds(轮询数组中),继续轮询,如果是新的链接,就重复上面的操作,如果是已经建立的链接,就执行该链接上读取到的command,也就是connection.processOneCommand()方法。
代码语言:javascript复制Android P之前processOneCommand的方法名是runOnce
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
代码语言:javascript复制Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
//读取命令
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
......
}
......
parsedArgs = new Arguments(args);
......
//fork子进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
if (pid == 0) {
// 子进程中(应用进程中)
zygoteServer.setForkChild();
......
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
//父进程中(zygote)
......
return null;
}
} finally {
......
}
}
从当前链接socket中读取启动命令。如果读取成功,zygote将会fork出子进程,并且返回可以调用启动类的main方法的runnable(也就是④中的caller)
zygoteServer.setForkChild()将mIsForkChild全局变量设为true。 我们接下来分析handleChildProc()方法 frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
代码语言:javascript复制private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,FileDescriptor pipeFd, boolean isZygote) {
//关闭ZygoteConnection中的socket链接
closeSocket();
......
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
......
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,null /* classLoader */);
} else {
......
}
}
从ZygoteInit.zygoteInit()开始就和③中分析的代码一模一样了,这里就不重复分析了,③中返回的是可以调用SystemServer的main方法的Runnable,而④中返回的是可以调用ActivityThread的main方法的Runnable。
总结
上面我们提到Zygote进程是第一个java进程,但整篇分析下来,java进程其实也是运行在c 进程之上的,只不过是java虚拟机屏蔽了这一切。zygote进程的启动,是从c 世界一步一步过渡到java世界,每个世界做了自己的准备工作。
c 世界(app_main.cpp入口):
代码语言:javascript复制动态加载虚拟机动态库,启动java虚拟机
注册JNI本地函数,减轻虚拟机负担
装载ZygoteInit到java虚拟机,正式进入java世界
java世界(ZygoteInit.java入口):
代码语言:javascript复制绑定套接字,用来接收新Android应用程序运行请求
预加载Android资源,提高应用进程启动速度
启动并运行SystemServer(运行AMS、PMS等核心服务)
处理新Android应用程序运行请求