Android 5.1 Lollipop的Zygote分析——下篇
来源:互联网 发布:1-10伪随机数生成算法 编辑:程序博客网 时间:2024/05/20 06:10
上一篇结尾的时候,说过AppRuntime的start()最后会加载Java层次的ZygoteInit类(com.android.internal.os.ZygoteInit),并调用其main函数。
ZygoteInit要做一些和Android平台紧密相关的重要动作,比如创建LocalServerSocket对象、预加载一些类以及资源、启动“Android系统服务”.
ZygoteInit类源码位置:Android源码/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
12345678910111213141516171819202122232425262728293031
public static void main(String argv[]) { try { // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = "zygote";//----------------------------------- ................................................. registerZygoteSocket(socketName);//-----------------------注册zygote套接字 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload();//------------------------------------------------预加载资源 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); ................................................. if (startSystemServer) {//-------------------------------- 启动 system server 服务 startSystemServer(abiList, socketName); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(abiList);//------------------------------------ closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; }}
registerZygoteSocket
其中registerZygoteSocket函数代码如下图所示
代码中 ANDROID_SOCKET_PREFIX 定义如下:
1
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
那么fullSocketName就是ANDROID_SOCKET_zygote了。要想知道这个环境变量,是怎么来的,那就要先分析init进程了,这不是我们的重点,等后面分析init进程的时候,在详细讨论这个变量的由来。
这里先简单说一下吧。在前面提到的关于zygote的rc配置文件,例如init.zygote32.rc中,有这么个option内容:
1
socket zygote stream 660 root system
说明zygote进程需要一个名为“zygote”的“流型(stream)”socket,当init进程真的启动zygote服务时,会走到service_start(),该函数会检查到zygote服务,需要一个“流型(stream)”的socket,那么便会在/dev/socket中为其创建一个名为zygote的流类型socket,并把新建的socket的文件描述符记录在以“ANDROID_SOCKET_zygote”的环境变量中。
那么ZygoteInit类中main函数下面的代码就清楚了其含义了:
12
String env = System.getenv(ANDROID_SOCKET_ENV);fileDesc = Integer.parseInt(env);
从环境变量的字符串中解析出文件描述符,然后创建LocalServerSocket对象,并将其记录在静态变量sServerSocket中,以后zygote进程会循环监听这个socket,一旦accept到连接请求,就创建命令连接(Command Connection)。监听动作的细节是在runSelectLoop()中。
预先加载类和资源
预先加载类
注册完socket接口,ZygoteInit会预加载一些类,这些类记录在Android源码/frameworks/base/preloaded-classes文本文件里:
12345678910111213
# Classes which are preloaded by com.android.internal.os.ZygoteInit.# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.# MIN_LOAD_TIME_MICROS=1250# MIN_PROCESSES=10........................................[Landroid.accounts.Account;[Landroid.animation.Animator;[Landroid.animation.Keyframe$FloatKeyframe;[Landroid.animation.Keyframe$IntKeyframe;[Landroid.animation.PropertyValuesHolder;[Landroid.app.FragmentState;[Landroid.app.LoaderManagerImpl;........................................
这个文件开头已经说的很清楚了,预先加载的这些类,每个加载时间都至少是1250微秒。Android 5.1中预先加载的类大约有3000个,可想而已Android启动的时候,花在这上面的时间可不少呢。preload函数中会调研preloadClasses()的函数预先加载这些类。
预先加载资源
preload函数中还会利用preloadResources()函数预先加载一些资源,这些资源记录在Android源码/frameworks/base/core/res/res/values/arrays.xml中。
基本上有两大类资源:
1)一类和图片有关(preloaed_drawables)
2)另一类和颜色有关(preloaded_color_state_lists)
预先加载的其他资源
preload函数还要调用下面两个函数还要预先加载opengl和一些so库。
123456789101112
private static void preloadSharedLibraries() { Log.i(TAG, "Preloading shared libraries..."); System.loadLibrary("android"); System.loadLibrary("compiler_rt"); System.loadLibrary("jnigraphics");}private static void preloadOpenGL() { if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) { EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); }}
启动system server服务
ZygoteInit的main()函数会调用startSystemServer()来启动system server,这是Android上层系统最重要的服务了。其大体做法是先fork一个子进程,然后在子进程中做一些初始化动作,继而执行SystemServer类的main()静态函数。需要注意的是,startSystemServer()并不是在函数体内直接调用Java类的main()函数的,而是通过抛异常的方式,在startSystemServer()之外加以处理的。
startSystemServer函数部分代码如下:
123456789101112131415161718192021222324252627282930313233343536373839404142
private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException { ................... /* 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, "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); // fork出系统服务对应的进程 pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } // 对新fork出的系统进程,执行handleSystemServerProcess() if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } handleSystemServerProcess(parsedArgs); } return true;}
Zygote.forkSystemServer
android源码/frameworks/base/core/java/com/android/internal/os/Zygote.java
12345678
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { VM_HOOKS.preFork(); int pid = nativeForkSystemServer( uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); VM_HOOKS.postForkCommon(); return pid;}
其中参数可以从下面获取:
12345678910
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, "--runtime-init", "--nice-name=system_server", "com.android.server.SystemServer",};
nativeForkSystemServer()是个native成员函数,其对应的C++层代码位置:Android源码/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp :
123456789101112131415161718192021222324
static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities) { pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL, NULL, NULL); if (pid > 0) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); gSystemServerPid = pid; // There is a slight window that the system server process has crashed // but it went unnoticed because we haven't published its pid yet. So // we recheck here just to make sure that all is well. int status; if (waitpid(pid, &status, WNOHANG) == pid) { ALOGE("System server process %d has died. Restarting Zygote!", pid); RuntimeAbort(env); } } return pid;}
forkAndSpecializeCommon()内部其实会调用fork(),而后设置gid、uid等信息
handleSystemServerProcess
startSystemServer()会在新fork出的子进程中调用handleSystemServerProgress(),让这个新进程成为真正的系统进程(SystemServer进程)
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
/** * Finish remaining work for the newly forked system server process. */ private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket();//------------------因为子进程是system server 不是zygote,所以要关闭zygote socket // 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);//----------------niceName 是 system_server } 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, 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. */ // 此时的remainingArgs就是”com.android.server.SystemServer” RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */ }
因为当前已经不是运行在zygote进程里了,所以zygote里的那个监听socket就应该关闭了.在handleSystemServerProcess()函数里,parsedArgs.niceName就是“system_server”,而且因为parsedArgs.invokeWith没有指定,所以其值为null,于是程序会走到RuntimeInit.zygoteInit().
Android源码/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
1234567891011
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); redirectLogStreams();//-------------在新fork出的系统进程里,需要重新定向系统输出流 commonInit(); nativeZygoteInit(); applicationInit(targetSdkVersion, argv, classLoader); }
上面调用的nativeZygoteInit()是个JNI函数,在AndroidRuntime.cpp文件中可以看到:
12345678910111213141516
/* * JNI registration. */static JNINativeMethod gMethods[] = { { "nativeFinishInit", "()V", (void*) com_android_internal_os_RuntimeInit_nativeFinishInit }, { "nativeZygoteInit", "()V", (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit }, { "nativeSetExitWithoutCleanup", "(Z)V", (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },};static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz){ gCurRuntime->onZygoteInit();}
gCurRuntime是C++层的AndroidRuntime类的静态变量。在AndroidRuntime构造之时,gCurRuntime = this
其中onZygoteInit是一个虚函数,是有AndroidRuntime的子类AppRuntime负责实现的。
Android源码/framework/base/cmds/app_process/App_main.cpp
123456789
virtual void onZygoteInit() { // Re-enable tracing now that we're no longer in Zygote. atrace_set_tracing_enabled(true); sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); }
里面构造了进程的ProcessState全局对象,而且启动了线程池。 这就涉及到了Binder机制的知识了,关于Binder后面再讲。
也就是说system server进程内部会开启一个线程池。
在来看applicationInit()函数的代码如下:
123456789101112131415161718
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { nativeSetExitWithoutCleanup(true); 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; } // Remaining arguments are passed to the start class's static main invokeStaticMain(args.startClass, args.startArgs, classLoader);
1234567891011121314151617181920212223242526272829303132333435
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 });//-----------------注意看这里的 main } 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函数中最后抛出了异常。这相当于一个“特殊的goto语句”!上面的cl = Class.forName函数,其实加载的就是SystemServer类。这个类名是从前文的parsedArgs.remainingArgs得来的,其值就是“com.android.server.SystemServer”。此处抛出的异常,会被本进程的catch语句接住,在那里才会执行SystemServer类的main()函数
如下图所示,新fork出的SystemServer子进程直接跳过了中间那句runSelectLoop(),去执行caller.run()去了,也就是说这个run函数是在子进程中执行的。
父进程Zygote在fork动作后,会退出startSystemServer()函数,并走到runSelectLoop(),从而进入一种循环监听状态,每当Activity Manager Service向它发出“启动新应用进程”的命令时,它又会fork一个子进程,并在子进程里抛出一个异常,这样子进程还是会跳转到catch一句。
现在看以下 SystemServer类的main函数:
frameworks/base/services/java/com/android/server/SystemServer.java
123456
/** * The main entry point from zygote. */public static void main(String[] args) { new SystemServer().run();}
可见创建了SystemServer对象,并且执行其run函数:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
private void run() { // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it shortly. if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // Here we go! Slog.i(TAG, "Entered the Android system server!"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system // property so that it is in sync. We can't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Enable the sampling profiler. if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); mProfilerSnapshotTimer = new Timer(); mProfilerSnapshotTimer.schedule(new TimerTask() { @Override public void run() { SamplingProfilerIntegration.writeSnapshot("system_server", null); } }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); } // Mmmmmm... more memory! VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Some devices rely on runtime fingerprint generation, so make sure // we've defined it before booting further. Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true); // Ensure binder calls into the system always run at foreground priority. BinderInternal.disableBackgroundScheduling(true); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); // Initialize native services. System.loadLibrary("android_servers"); nativeInit(); // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Start services. try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } // For debug builds, log event loop stalls to dropbox for analysis. if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
可见会初始化 native services.
12
System.loadLibrary("android_servers");nativeInit();
监听zygote socket
ZygoteInit的main()函数在调用完startSystemServer()之后,zygote进程会进一步走到runSelectLoop()
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); FileDescriptor[] fdArray = new FileDescriptor[4]; fds.add(sServerSocket.getFileDescriptor());//------------------------sServerSocket就是zygote socket文件描述符 peers.add(null); int loopCount = GC_LOOP_COUNT; while (true) { int index; /* * Call gc() before we block in select(). * It's work that has to be done anyway, and it's better * to avoid making every child do it. It will also * madvise() any free memory as a side-effect. * * Don't call it every time, because walking the entire * heap is a lot of overhead to free a few hundred bytes. */ if (loopCount <= 0) { gc(); loopCount = GC_LOOP_COUNT; } else { loopCount--; } try { fdArray = fds.toArray(fdArray);//-----------------------------fdArry中就包含了zygote socket文件描述符了 index = selectReadable(fdArray); } catch (IOException ex) { throw new RuntimeException("Error in select()", ex); } if (index < 0) { throw new RuntimeException("Error in select()"); } else if (index == 0) {//-----------------------------------------对应的zygote socket有数据可读 ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDescriptor()); } else {//-------------------------------------------------对应其他文件描述符有数据可读 boolean done; done = peers.get(index).runOnce(); if (done) { peers.remove(index); fds.remove(index); } } }}
在一个while循环中,不断调用selectReadable()。该函数是个native函数,对应C++层的com_android_internal_os_ZygoteInit_selectReadable()。
Android源码/frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp
1234567
static JNINativeMethod gMethods[] = {................................................................. { "selectReadable", "([Ljava/io/FileDescriptor;)I", (void *) com_android_internal_os_ZygoteInit_selectReadable }, { "createFileDescriptor", "(I)Ljava/io/FileDescriptor;", (void *) com_android_internal_os_ZygoteInit_createFileDescriptor }};
1234567891011121314151617181920
static jint com_android_internal_os_ZygoteInit_selectReadable (JNIEnv *env, jobject clazz, jobjectArray fds){ . . . . . . int err; do { err = select (nfds, &fdset, NULL, NULL, NULL); } while (err < 0 && errno == EINTR); . . . . . . for (jsize i = 0; i < length; i++) { jobject fdObj = env->GetObjectArrayElement(fds, i); . . . . . . int fd = jniGetFDFromFileDescriptor(env, fdObj); . . . . . . if (FD_ISSET(fd, &fdset)) { return (jint)i; } } return -1;}
主要就是调用select()而已。在Linux的socket编程中,select()负责监视若干文件描述符的变化情况,我们常见的变化情况有:读、写、异常等等。
在zygote中,err = select (nfds, &fdset, NULL, NULL, NULL);一句的最后三个参数都为NULL,表示该select()操作只打算监视文件描述符的“读变化”,而且如果没有可读的文件,select()就维持阻塞状态。
在被监视的文件描述符数组(fds)中,第一个文件描述符对应着“zygote接收其他进程连接申请的那个socket(及sServerSocket)”,一旦它发生了变化,我们就尝试建立一个ZygoteConnection。
新创建的ZygoteConnection会被再次写入文件描述符数组(fds):
1
fds.add(newPeer.getFileDescriptor());
如果select动作发现文件描述符数组(fds)的其他文件描述符有东西可读了,说明有其他进程通过某个已建立好的ZygoteConnection发来了命令,此时我们需要调用runOnce()。
123456789101112131415161718192021222324252627282930313233343536
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { String args[]; Arguments parsedArgs = null; FileDescriptor[] descriptors; . . . . . . args = readArgumentList();//---------------------------------------------------------------- descriptors = mSocket.getAncillaryFileDescriptors(); . . . . . . int pid = -1; FileDescriptor childPipeFd = null; FileDescriptor serverPipeFd = null; try { parsedArgs = new Arguments(args); . . . . . . pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName); } . . . . . . if (pid == 0) { // in child IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); return true; } else { // in parent...pid of < 0 means failure IoUtils.closeQuietly(childPipeFd); childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } . . . . . .}
runOnce()中从socket中读取参数数据的动作是由readArgumentList()完成的,该函数的代码如下
12345678910111213141516171819
private String[] readArgumentList() throws IOException { int argc; . . . . . . String s = mSocketReader.readLine(); . . . . . . argc = Integer.parseInt(s); . . . . . . String[] result = new String[argc]; for (int i = 0; i < argc; i++) { result[i] = mSocketReader.readLine(); if (result[i] == null) { // We got an unexpected EOF. throw new IOException("truncated request"); } } return result;}
AMS会想这个socke写入参数。AMS需要启动一个新进程时,会调用类似下面的句子:
123
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, null);
包括ActivityThread类名等重要信息的参数,最终就会通过socket传递给zygote。
runOnce()在读完参数之后,会进一步调用到handleChildProc()。该函数会间接抛出特殊的MethodAndArgsCaller异常,只不过此时抛出的异常携带的类名为ActivityThread,前面我们提到的类名是SystemServer。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { closeSocket();//--------------------------------------------因为不是zygote进程了,所以肯定要先关闭socket了 ZygoteInit.closeServerSocket(); . . . . . . if (parsedArgs.niceName != null) { Process.setArgV0(parsedArgs.niceName); } if (parsedArgs.runtimeInit) { if (parsedArgs.invokeWith != null) { WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, pipeFd, parsedArgs.remainingArgs); } else { RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs); } } else { String className; . . . . . . className = parsedArgs.remainingArgs[0]; . . . . . . String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1]; System.arraycopy(parsedArgs.remainingArgs, 1, mainArgs, 0, mainArgs.length); if (parsedArgs.invokeWith != null) { WrapperInit.execStandalone(parsedArgs.invokeWith, parsedArgs.classpath, className, mainArgs); } else { ClassLoader cloader; if (parsedArgs.classpath != null) { cloader = new PathClassLoader(parsedArgs.classpath, ClassLoader.getSystemClassLoader()); } else { cloader = ClassLoader.getSystemClassLoader(); } try { ZygoteInit.invokeStaticMain(cloader, className, mainArgs);//-----------------------很熟悉吧,忘了的话,往上看 } catch (RuntimeException ex) { logAndPrintError(newStderr, "Error starting.", ex); } } }}
Zygote进程实际上是利用fork()创建新进程。如果fork()出的新进程是system server,那么其最终执行的就是SystemServer类的main()函数,而如果fork()出的新进程是普通的用户进程的话,那么其最终执行的就是ActivityThread类的main()函数。
原文地址: http://www.iloveandroid.net/2015/09/21/Zygote_2/
- Android 5.1 Lollipop的Zygote分析——下篇
- Android 5.1 Lollipop的Zygote分析——上篇
- android 的Zygote 分析
- android 的Zygote 分析
- Android zygote分析——学习笔记
- android 的Zygote 分析(转)
- Android -- 系统进程Zygote的启动分析
- Android Zygote源码分析
- 一个有意思的麻烦android 5.1 Lollipop
- Zygote的分析
- Zygote进程【1】——Zygote的诞生
- Zygote进程【2】——Zygote的分裂
- Android开机流程分析 -- Zygote
- Android Zygote进程源码分析
- Android Zygote进程源码分析
- Android系统进程Zygote启动过程的源代码分析
- Android系统进程Zygote启动过程的源代码分析
- Android系统进程Zygote启动过程的源代码分析
- 高通平台手机开发之Sensor
- 前置声明以及在 Callback 实现中的应用
- UITableView
- mysql优化(1)show命令 慢查询日志 explain profiling
- Maven3.3.3安装部署教程
- Android 5.1 Lollipop的Zygote分析——下篇
- ZOO
- mysql优化(2)索引优化 配置优化
- 屏幕适配
- cocos2dx-js3.9 手动绑定JS到C++
- 【hdu1241】Oil Deposits——dfs/bfs
- POJ2782(贪心)
- 如何建立自身的自信
- 在javascript中innerHTML和innerText的区别,以及innerHTML和innerText在各个版本浏览器的兼容性问题