上一篇 说了 开机的init 进程,这里说明下zygote 进程 借鉴一下其他大佬的说明
所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。
我们看zygote 的源码 主要是通过
http://androidxref.com/6.0.0_r1/xref/frameworks/base/cmds/app_process/app_main.cpp
这个文件 是zygote 的源代码 通过这个cpp 生成可执行文件所以我们直接从它的main 方法 看起
int main(int argc, char* const argv[])
187{
...
//创建了一个appRuntime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
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;
niceName = ZYGOTE_NICE_NAME;
//记录bool 值 startsystemserver 为true
} 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) {
//到这里会调用 start 方法传入一个 com.android.internal.os.ZygoteInit 这是一
个java 文件名
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
.......
上面主要是解析参数 创建了一个AppRuntime 最后调用了它的start 方法 然后我们 看一看这个AppRuntime 到底是个什么东西 源码位置
http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/jni/AndroidRuntime.cpp
我们直接看它的start
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
// 到这里开始创建java 虚拟机。。 还有jni的一些初始化
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//下面的东西 我们应该很熟悉都是jni 的操作。。。 说明我们即将开始进去java 文件了。。。
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
// strArray= new String[options.size() + 1];
stringClass = env->FindClass("java/lang/String");
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
// strArray[0] = "com.android.internal.os.ZygoteInit"
classNameStr = env->NewStringUTF(className);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}
// 其实这个classname 就是我们传入的。。"com/android/internal/os/ZygoteInit"
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);//找到了jclass 对象
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
// 获取 ZygoteInit.java 的 main方法的methodid
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 方法 然后开始调用java 文件了。。
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
...
}
上面通过jni 调用了 zygoteinit.java 的main 方法 ,激动人心的java 时刻终于来临 我们看看 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; //找到参数 为 start system server 标记一个bool
} 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]);
}
}
registerZygoteSocket(socketName);//创建一个zygote 的socket
preload(); //预加载一些资源 主要是系统的
。。。。。。。
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
if (startSystemServer) {
startSystemServer(abiList, socketName);//开启systemserver
}
//死循环 等待接受消息 孵化进程
runSelectLoop(abiList);
//都完事了 关闭socket
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
然后我们看看startsystemserver 的这个方法的源码
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
/* 配置一些命令 参数用于启动 systemserver */
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);
/* 调用zygote 的fork 孵化systemserver进程 (native 方法) */
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); //处理systemserver 进程相关
}
return true;
}
这上面就是孵化了systemserver 进程 然后 调用handleSystemserverProcess 方法 我们 接下来看看 handleSystemserverprocess 方法
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.invokeWith != null) { 、
//执行application命令
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
//创建classloader 。。 看看这是什么。。这不是熟悉的pathclassloader 吗。他的父类是systemclassloader
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl); //设置当前线程的classloader 为pathclassloader
}
//最后又整到了 runtimeInit.zygoteinit 方法
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
我们看看 RuntimeInit 源码位置 http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
我们直接看applicaitoninit 方法
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
我们接着看看 invokestaticmain
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
//反射拿到 class 对象 也就是 systemserver.java
cl = Class.forName(className, true, classLoader);
} ex);
Method m;
try {
//拿到它的main 方法
m = cl.getMethod("main", new Class[] { String[].class });
}
//调用 zygoteinit 的methodcaller 方法
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
又 折腾到了zygoteinit 我们回来看看这个methodandargscaller 方法
public static class MethodAndArgsCaller extends Exception
implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//反射执行 了main 方法 也就是 systemserver 的main
mMethod.invoke(null, new Object[] { mArgs });
}
}
折腾一圈儿 终于到了SystemServer 了。源码位置 http://androidxref.com/6.0.0_r1/xref/frameworks/base/services/java/com/android/server/SystemServer.java
我们看看它的main 方法做了什么 下面的参考了一个大佬的文章 末尾会附上大佬的博文地址 他 注释的很详细
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
//开启日志跟踪
traceBeginAndSlog("InitBeforeStartServices");
//如果设备时钟在1970之前,则重新赋值为1970
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//如果没有设置时区,默认为格林威治时间(GMT)
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
SystemProperties.set("persist.sys.timezone", "GMT");
}
//检查设置语言环境
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
//系统服务器不应该进行非单向调用
Binder.setWarnOnBlocking(true);
//系统服务器应该始终加载安全标签
PackageItemInfo.setForceSafeLabels(true);
//停用SQLiteCompatibilityWalFlags,直到初始化设置提供程序
SQLiteCompatibilityWalFlags.init(null);
//----------此处开始进入Android系统服务-----------
int uptimeMillis = (int) SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
}
//如果自上次引导以来运行时发生切换(例如什么时候)在OTA中删除旧的运行时),则设置系统属性,使其同步
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
//更多内存
VMRuntime.getRuntime().clearGrowthLimit();
//系统服务器必须一直运行,因此需要尽可能高效地使用内存。
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//有些设备依赖于运行时指纹生成,因此在进一步引导之前请确保我们已经定义了它。
Build.ensureFingerprintProperty();
//在系统服务器中,在没有显式指定用户的情况下访问环境路径是错误的。
Environment.setUserRequired(true);
//在系统服务器中,任何传入的包都应该被解除锁定,以避免抛出BadParcelableException。
BaseBundle.setShouldDefuse(true);
//在系统服务器中,当打包异常时,包括堆栈跟踪
Parcel.setStackTraceParceling(true);
//确保对系统的绑定调用始终以前台优先级运行。
BinderInternal.disableBackgroundScheduling(true);
//增加system_server中绑定器线程的数量
BinderInternal.setMaxThreads(sMaxBinderThreads);
//准备创建主线程(当前线程).
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper(); //创建主线程
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
//加载libandroid_servers.so库
System.loadLibrary("android_servers");
//检查我们上次试着关闭时是否失败
performPendingShutdown();
//初始化系统上下文
createSystemContext();
//创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//为可以并行化的init任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd();
}
//开启系统服务
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
throw ex;
} finally {
traceEnd();
}
//......
//开启主线程,进入死循环,处理各种事件消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
//此处稍微注意,全局上下文是通过ActivityThread创建的
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
以上的run方法大概可以分为下面几步:
- 首先设置时间、市区、语言等环境,然后设置虚拟机的一些属性参数
- 然后调用Looper.prepareMainLooper()创建主线程,即我们熟知的UI线程
- 接着加载android_servers底层库,初始化系统上下文对象
- 再接着就是初始化各种系统服务,例如:SystemServiceManager、ActivityServiceManager、WifiService等
- 最后调用Looper.loop()开启死循环,以处理各种事件消息
参考文章