android frameworks之zygote进程
zygote进程是各个应用进程的鼻祖,每个app的进程是由zygote进程创建出来的,即app进程的父进程为zygote进程。
在系统启动时,加载bootloader,启动内核,创建init进程,在init进程中,解析init.rc,init.rc包含启动zygote进程的服务,进而启动zygote进程。
在linux中,进程是由fork()创建的,fork出的子进程除了一些内核的核心数据跟父进程不同外,其余的数据、内存都是和父进程共享的,fork()出的子进程返回值为0,父进程的返回值为父进程的pid
1、init.rc
init.rc中是通过import方式引入文件的,引入的文件通过ro.zygote的属性来控制
\system\core\rootdir\init.rc
import /init.${ro.zygote}.rc
ro.zygote的属性值可设置的值有:zygote32,zygote32_64,zygote64,zygote64_32,因此在system/core/rootdir/目录下有四个和zygote相关的rc文件
zygote32:32位模式
zygote32_64:以32位模式为主,64位模式为辅
zygote64:64位模式
zygote64_32:以64位模式为主,32位模式为辅
zygote32和zygote64一样,只是zygote64执行的是app_process64的进程;zygote32和zygote32_64的区别在宇zygote32_64多了启动zygote_secondary的进程
init.zytote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary 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
init.zygote32_64.rc
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary 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
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
以zygote32为例。
2、app_process的源码路径是在frameworks/base/cmds/app_process下,只有app_main.cpp文件,我们直接看它的main方法
int main(int argc, char* const argv[])
{
.................
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//创建AppRuntime实例
.................
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {/会进入这个分支
zygote = true;
niceName = ZYGOTE_NICE_NAME;//niceName=zygote
} 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;
}
}
....................
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.");
}
}
在main方法里,主要做了创建runtime,解析参数,然后把com.android.internal.os.ZygoteInit传到runtime.start.
\frameworks\base\core\jni\AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
................
JniInvocation jni_invocation;
jni_invocation.Init(NULL);//初始化art
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {//启动虚拟机
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) {//注册jni
ALOGE("Unable to register all android natives\n");
return;
}
.................
char* slashClassName = toSlashClassName(className != NULL ? 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 {
env->CallStaticVoidMethod(startClass, startMeth, strArray);//jni反射,由C、c++调用java,这里startClass为ZygoteInit,即调用ZygoteInit.java的main方法
...............
}
AndroidRuntime::start里初始化art,启动虚拟机,注册jni,然后通过CallStaticVoidMethod方法进入到ZygoteInit.java的main方法。这里只是大概讲了一下流程,具体分析可看我的另外一篇文章《Android 通过bin二进制程序调用jar原理》
android4.4之前采用的是dalvik虚拟机,在android5.0开始用art虚拟机代替dalvik。Dalvik虚拟机也算是java虚拟机,只不过它执行的是dex文件,而不是class文件,并且dalvik虚拟机包含解析器,用来执行dex字节码,在运行时动态地将dex字节码转成本地机器码,然后再执行,这显然存在着效率问题。如果在运行时无需翻转换直接执行本地机器码,那效率会得到提升,因此art主要是解决这一问题。在应用安装时,art直接将dex转换为本地机器码,所以android5.0后APP的安装速度明显比之前的慢,但在运行效率方面也得到显著提升。在app安装中主要是通过PackageManagerServer的服务通过请求installd进程来执行的。
3、我们接着看ZygoteInit.java的main方法
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
..............................
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {//进入这个分支
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = 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)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);//isPrimaryZygote为truen,sockename为:zygote
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
............................
//创建socket
Zygote.initNativeState(isPrimaryZygote);
ZygoteHooks.stopZygoteNoThreadCreation();
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);//创建进程,【见3.1小节】
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
........................
if (caller != null) {
caller.run();
}
}
3.1小节
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,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteArguments(args);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
//通过native的fork()创建出一个进程
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {//返回值为0的是子进程
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
//查看参数配没有为mInvokeWith配置,因此parsedArgs.mInvokeWith==null,进入else分支
if (parsedArgs.mInvokeWith != null) {
String[] args = parsedArgs.mRemainingArgs;
// 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(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
createSystemServerClassLoader();
ClassLoader cl = sCachedSystemServerClassLoader;
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, cl);//ZygoteInit.zygoteInit里主要做log和trace的配置,初始化zygote
}
/* should never reach here */
}
ZygoteInit.zygoteInit做log和trace的配置,通过jni初始化zygote,然后调起RuntimeInit.findStaticMain
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);//通过参数配置可以跟踪到className为com.android.server.SystemServer
} 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);
}
return new MethodAndArgsCaller(m, argv);
}
在ZygoteInit.java的main方法包含各个函数的调用都主要是做了三个事情:创建socke,创建进程,通过反射调用com.android.server.SystemServer的main方法。
4、com.android.server.SystemServer.main()
frameworks\base\services\java\com\android\server\SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
....................................
//设置一些属性值
...............................
//配置运行环境
VMRuntime.getRuntime().clearGrowthLimit();
......................
Looper.prepareMainLooper();//开启looper
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
System.loadLibrary("android_servers");//加载libandroid_servers.so
// Debug builds - allow heap profiling.
if (Build.IS_DEBUGGABLE) {
initZygoteChildHeapProfiling();
}
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();//创建上下文
// 把SystemServiceManager添加到服务列表
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// 启动核心的服务,大概会启动90多种服务
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
......................................
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}