application process startup, activity native thread will call activitmanagerservice to attach application.
在Zygote进程启动过程的源代码分析一文中介绍到,Zygote是java世界的开创者,所有的java应用进程都是通过Zygote孵化出来的。我们知道在Android应用程序框架层中,ActivityManagerService组件负责管理Android应用程序的创建,ActivityManagerService也是运行在独立的进程SystemServer中,SystemServer进程启动过程源码分析中介绍了SystemServer进程是如果通过开启线程来启动各种服务,ActivityManagerService也是System Server启动的服务之一。
ActivityManagerService请求创建应用程序进程
当系统决定要在一个新的进程中启动一个Activity或者Service时,它就会创建一个新的进程,ActivityManagerService通过调用startProcessLocked函数来为应用程序启动新的进程。
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
- final ProcessRecord startProcessLocked(String processName,
- ApplicationInfo info, boolean knownToBeDead, int intentFlags,
- String hostingType, ComponentName hostingName, boolean allowWhileBooting,
- boolean isolated) {
- ProcessRecord app;
- //是否在现有进程中启动
- if (!isolated) {
- //从现有进程表mProcessNames中查找相应的进程描述符ProcessRecord
- app = getProcessRecordLocked(processName, info.uid);
- } else {
- // If this is an isolated process, it can't re-use an existing process.
- app = null;
- }
- // We don't have to do anything more if:
- // (1) There is an existing application record; and
- // (2) The caller doesn't think it is dead, OR there is no thread
- // object attached to it so we know it couldn't have crashed; and
- // (3) There is a pid assigned to it, so it is either starting or
- // already running.
- if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
- + " app=" + app + " knownToBeDead=" + knownToBeDead
- + " thread=" + (app != null ? app.thread : null)
- + " pid=" + (app != null ? app.pid : -1));
- if (app != null && app.pid > 0) {
- if (!knownToBeDead || app.thread == null) {
- // We already have the app running, or are waiting for it to
- // come up (we have a pid but not yet its thread), so keep it.
- if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
- // If this is a new package in the process, add the package to the list
- app.addPackage(info.packageName);
- return app;
- } else {
- // An application record is attached to a previous process,
- // clean it up now.
- if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
- handleAppDiedLocked(app, true, true);
- }
- }
- String hostingNameStr = hostingName != null
- ? hostingName.flattenToShortString() : null;
- if (!isolated) {
- if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
- // If we are in the background, then check to see if this process
- // is bad. If so, we will just silently fail.
- if (mBadProcesses.get(info.processName, info.uid) != null) {
- if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
- + "/" + info.processName);
- return null;
- }
- } else {
- // When the user is explicitly starting a process, then clear its
- // crash count so that we won't make it bad until they see at
- // least one crash dialog again, and make the process good again
- // if it had been bad.
- if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
- + "/" + info.processName);
- mProcessCrashTimes.remove(info.processName, info.uid);
- if (mBadProcesses.get(info.processName, info.uid) != null) {
- EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,info.processName);
- mBadProcesses.remove(info.processName, info.uid);
- if (app != null) {
- app.bad = false;
- }
- }
- }
- }
- if (app == null) {
- //在ActivityManagerService中为新进程创建一个ProcessRecord实例
- app = newProcessRecordLocked(null, info, processName, isolated);
- if (app == null) {
- Slog.w(TAG, "Failed making new process record for "
- + processName + "/" + info.uid + " isolated=" + isolated);
- return null;
- }
- //添加到进程列表中
- mProcessNames.put(processName, app.uid, app);
- //如果当前服务运行在独立进程中,添加到独立进程表mIsolatedProcesses中
- /**
- * SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
- * The currently running isolated processes.
- */
- if (isolated) {
- mIsolatedProcesses.put(app.uid, app);
- }
- } else {
- // If this is a new package in the process, add the package to the list
- app.addPackage(info.packageName);
- }
- // If the system is not ready yet, then hold off on starting this
- // process until it is.
- if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) {
- /**
- * final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
- * List of records for processes that someone had tried to start before the
- * system was ready. We don't start them at that point, but ensure they
- * are started by the time booting is complete.
- */
- if (!mProcessesOnHold.contains(app)) {
- mProcessesOnHold.add(app);
- }
- if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
- return app;
- }
- //调用startProcessLocked启动新的应用程序进程
- startProcessLocked(app, hostingType, hostingNameStr);
- return (app.pid != 0) ? app : null;
- }
frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
- private final void startProcessLocked(ProcessRecord app,
- String hostingType, String hostingNameStr) {
- if (app.pid > 0 && app.pid != MY_PID) {
- synchronized (mPidsSelfLocked) {
- mPidsSelfLocked.remove(app.pid);
- mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
- }
- app.pid = 0;
- }
- //系统准备好了,马上启动服务,因此如果mProcessesOnHold列表中包含当前启动的服务,则需移除
- if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
- "startProcessLocked removing on hold: " + app);
- mProcessesOnHold.remove(app);
- //唤醒进程信息收集线程
- updateCpuStats();
- System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
- mProcDeaths[0] = 0;
- try {
- int uid = app.uid;
- int[] gids = null;
- if (!app.isolated) {
- try {
- gids = mContext.getPackageManager().getPackageGids(
- app.info.packageName);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Unable to retrieve gids", e);
- }
- }
- if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
- if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
- && mTopComponent != null
- && app.processName.equals(mTopComponent.getPackageName())) {
- uid = 0;
- }
- if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
- && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
- uid = 0;
- }
- }
- //设置应用程序进程创建方式
- int debugFlags = 0;
- if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
- debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
- // Also turn on CheckJNI for debuggable apps. It's quite
- // awkward to turn on otherwise.
- debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
- }
- // Run the app in safe mode if its manifest requests so or the
- // system is booted in safe mode.
- if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
- Zygote.systemInSafeMode == true) {
- debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
- }
- if ("1".equals(SystemProperties.get("debug.checkjni"))) {
- debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
- }
- if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
- debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
- }
- if ("1".equals(SystemProperties.get("debug.assert"))) {
- debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
- }
- //它调用了Process.start函数开始为应用程序创建新的进程,
- //它传入一个第一个参数为"android.app.ActivityThread",这就是进程初始化时要加载的Java类了,
- //把这个类加载到进程之后,就会把它里面的静态成员函数main作为进程的入口点,
- Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
- app.processName, uid, uid, gids, debugFlags,
- app.info.targetSdkVersion, null);
- BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
- synchronized (bs) {
- if (bs.isOnBattery()) {
- app.batteryStats.incStartsLocked();
- }
- }
- EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
- app.processName, hostingType,
- hostingNameStr != null ? hostingNameStr : "");
- //如果启动的进程是一个持久进程,则添加到Watchdog中监控
- if (app.persistent) {
- Watchdog.getInstance().processStarted(app.processName, startResult.pid);
- }
- StringBuilder buf = mStringBuilder;
- buf.setLength(0);
- buf.append("Start proc ");
- buf.append(app.processName);
- buf.append(" for ");
- buf.append(hostingType);
- if (hostingNameStr != null) {
- buf.append(" ");
- buf.append(hostingNameStr);
- }
- buf.append(": pid=");
- buf.append(startResult.pid);
- buf.append(" uid=");
- buf.append(uid);
- buf.append(" gids={");
- if (gids != null) {
- for (int gi=0; gi<gids.length; gi++) {
- if (gi != 0) buf.append(", ");
- buf.append(gids[gi]);
- }
- }
- buf.append("}");
- Slog.i(TAG, buf.toString());
- app.pid = startResult.pid;
- app.usingWrapper = startResult.usingWrapper;
- app.removed = false;
- //将新创建的进程描述符ProcessRecord保存到mPidsSelfLocked链表中
- /**
- * final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
- * All of the processes we currently have running organized by pid.
- * The keys are the pid running the application.
- */
- synchronized (mPidsSelfLocked) {
- this.mPidsSelfLocked.put(startResult.pid, app);
- Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
- msg.obj = app;
- mHandler.sendMessageDelayed(msg, startResult.usingWrapper
- ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
- }
- } catch (RuntimeException e) {
- // XXX do better error recovery.
- app.pid = 0;
- Slog.e(TAG, "Failure starting process " + app.processName, e);
- }
- if (LC_RAM_SUPPORT
- && ((app.info.flags & (ApplicationInfo.FLAG_SYSTEM)) == (ApplicationInfo.FLAG_SYSTEM))
- && (CONTACTS_PROCESS_NAME.equals(app.processName))) {
- app.isContactsProcess = true;
- }
- if (LC_RAM_SUPPORT && fixAdjList.containsKey(app.processName)) {
- app.fixAdj = fixAdjList.get(app.processName);
- Slog.v(TAG, "app[" + app.processName + "] has fix adj:" + app.fixAdj);
- }
- }
frameworks\base\core\java\android\os\Process.java
- public static final ProcessStartResult start(final String processClass,
- final String niceName,
- int uid, int gid, int[] gids,
- int debugFlags, int targetSdkVersion,
- String[] zygoteArgs) {
- try {
- return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, targetSdkVersion, zygoteArgs);
- } catch (ZygoteStartFailedEx ex) {
- Log.e(LOG_TAG,"Starting VM process through Zygote failed");
- throw new RuntimeException("Starting VM process through Zygote failed", ex);
- }
- }
frameworks\base\core\java\android\os\Process.java
- private static ProcessStartResult startViaZygote(final String processClass,
- final String niceName,
- final int uid, final int gid,
- final int[] gids,
- int debugFlags, int targetSdkVersion,
- String[] extraArgs)
- throws ZygoteStartFailedEx {
- synchronized(Process.class) {
- ArrayList<String> argsForZygote = new ArrayList<String>();
- // --runtime-init, --setuid=, --setgid=,
- // and --setgroups= must go first
- argsForZygote.add("--runtime-init");
- argsForZygote.add("--setuid=" + uid);
- argsForZygote.add("--setgid=" + gid);
- if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
- argsForZygote.add("--enable-jni-logging");
- }
- if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
- argsForZygote.add("--enable-safemode");
- }
- if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
- argsForZygote.add("--enable-debugger");
- }
- if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
- argsForZygote.add("--enable-checkjni");
- }
- if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
- argsForZygote.add("--enable-assert");
- }
- argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
- //TODO optionally enable debuger
- //argsForZygote.add("--enable-debugger");
- // --setgroups is a comma-separated list
- if (gids != null && gids.length > 0) {
- StringBuilder sb = new StringBuilder();
- sb.append("--setgroups=");
- int sz = gids.length;
- for (int i = 0; i < sz; i++) {
- if (i != 0) {
- sb.append(',');
- }
- sb.append(gids[i]);
- }
- argsForZygote.add(sb.toString());
- }
- if (niceName != null) {
- argsForZygote.add("--nice-name=" + niceName);
- }
- argsForZygote.add(processClass);
- if (extraArgs != null) {
- for (String arg : extraArgs) {
- argsForZygote.add(arg);
- }
- }
- //将通过Socket方式将参数列表发送给Zygote进程
- return zygoteSendArgsAndGetResult(argsForZygote);
- }
- }
frameworks\base\core\java\android\os\Process.java
- private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)
- throws ZygoteStartFailedEx {
- //创建一个客户端Socket,并连接到Zygote进程的Socket服务端
- openZygoteSocketIfNeeded();
- try {
- /**
- * See com.android.internal.os.ZygoteInit.readArgumentList()
- * Presently the wire format to the zygote process is:
- * a) a count of arguments (argc, in essence)
- * b) a number of newline-separated argument strings equal to count
- *
- * After the zygote process reads these it will write the pid of
- * the child or -1 on failure, followed by boolean to
- * indicate whether a wrapper process was used.
- */
- //将应用程序启动参数列表写入到Socket
- sZygoteWriter.write(Integer.toString(args.size()));
- sZygoteWriter.newLine();
- int sz = args.size();
- for (int i = 0; i < sz; i++) {
- String arg = args.get(i);
- if (arg.indexOf('\n') >= 0) {
- throw new ZygoteStartFailedEx(
- "embedded newlines not allowed");
- }
- sZygoteWriter.write(arg);
- sZygoteWriter.newLine();
- }
- sZygoteWriter.flush();
- //读取Zygote进程返回来的结果
- ProcessStartResult result = new ProcessStartResult();
- result.pid = sZygoteInputStream.readInt();
- if (result.pid < 0) {
- throw new ZygoteStartFailedEx("fork() failed");
- }
- result.usingWrapper = sZygoteInputStream.readBoolean();
- return result;
- } catch (IOException ex) {
- try {
- if (sZygoteSocket != null) {
- sZygoteSocket.close();
- }
- } catch (IOException ex2) {
- // we're going to fail anyway
- Log.e(LOG_TAG,"I/O exception on routine close", ex2);
- }
- sZygoteSocket = null;
- throw new ZygoteStartFailedEx(ex);
- }
- }
- private static void openZygoteSocketIfNeeded()
- throws ZygoteStartFailedEx {
- int retryCount;
- if (sPreviousZygoteOpenFailed) {
- /*
- * If we've failed before, expect that we'll fail again and
- * don't pause for retries.
- */
- retryCount = 0;
- } else {
- retryCount = 10;
- }
- /*
- * See bug #811181: Sometimes runtime can make it up before zygote.
- * Really, we'd like to do something better to avoid this condition,
- * but for now just wait a bit...
- */
- for (int retry = 0; (sZygoteSocket == null) && (retry < (retryCount + 1)); retry++ ) {
- if (retry > 0) {
- try {
- Log.i("Zygote", "Zygote not up yet, sleeping...");
- Thread.sleep(ZYGOTE_RETRY_MILLIS);
- } catch (InterruptedException ex) {
- // should never happen
- }
- }
- try {
- sZygoteSocket = new LocalSocket();
- //连接到Zygote进程的服务端zygote Socket
- sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, LocalSocketAddress.Namespace.RESERVED));
- sZygoteInputStream = new DataInputStream(sZygoteSocket.getInputStream());
- sZygoteWriter = new BufferedWriter(new OutputStreamWriter(
- sZygoteSocket.getOutputStream()),256);
- Log.i("Zygote", "Process: zygote socket opened");
- sPreviousZygoteOpenFailed = false;
- break;
- } catch (IOException ex) {
- //Socket操作失败,关闭该Socket
- if (sZygoteSocket != null) {
- try {
- sZygoteSocket.close();
- } catch (IOException ex2) {
- Log.e(LOG_TAG,"I/O exception on close after exception",ex2);
- }
- }
- sZygoteSocket = null;
- }
- }
- if (sZygoteSocket == null) {
- sPreviousZygoteOpenFailed = true;
- throw new ZygoteStartFailedEx("connect failed");
- }
- }
"--runtime-init"
"--setuid=x"
"--setgid=x"
"--enable-safemode"
"--enable-debugger"
"--enable-checkjni"
"--enable-assert"
"--setgroups=x"
"--nice-name=x"
"android.app.ActivityThread"
要启动一个新的应用程序进程,应用程序不能直接请求Zygote来fork出新进程,而是要通过SystemServer进程中的ActivityManagerService服务来请求Zygote进程。
Zygote进程孵化应用程序进程
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
- private static void runSelectLoopMode() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList();
- ArrayList<ZygoteConnection> peers = new ArrayList();
- FileDescriptor[] fdArray = new FileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- 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);
- //监听zygote Socket是否有客户端连接
- index = selectReadable(fdArray);
- } catch (IOException ex) {
- throw new RuntimeException("Error in select()", ex);
- }
- if (index < 0) {
- throw new RuntimeException("Error in select()");
- //zygote socket句柄中有事件到来,表示有客户端的socket连接
- } else if (index == 0) {
- //接收客户端连接请求,并将客户端请求添加到句柄池中监控
- ZygoteConnection newPeer = acceptCommandPeer();
- peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
- //客户端连接Socket有事件到来,表示SystemServer进程正在发送应用程序启动参数
- } else {
- boolean done;
- //孵化一个新的应用程序进程
- done = peers.get(index).runOnce();
- //从socket句柄池中移除客户连接socket句柄
- if (done) {
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
- boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
- String args[];
- Arguments parsedArgs = null;
- FileDescriptor[] descriptors;
- try {
- //读取参数
- args = readArgumentList();
- descriptors = mSocket.getAncillaryFileDescriptors();
- } catch (IOException ex) {
- Log.w(TAG, "IOException on command socket " + ex.getMessage());
- closeSocket();
- return true;
- }
- if (args == null) {
- // EOF reached.
- closeSocket();
- return true;
- }
- /** the stderr of the most recent request, if avail */
- PrintStream newStderr = null;
- if (descriptors != null && descriptors.length >= 3) {
- newStderr = new PrintStream(new FileOutputStream(descriptors[2]));
- }
- int pid = -1;
- FileDescriptor childPipeFd = null;
- FileDescriptor serverPipeFd = null;
- try {
- parsedArgs = new Arguments(args);
- applyUidSecurityPolicy(parsedArgs, peer);
- applyRlimitSecurityPolicy(parsedArgs, peer);
- applyCapabilitiesSecurityPolicy(parsedArgs, peer);
- applyInvokeWithSecurityPolicy(parsedArgs, peer);
- applyDebuggerSystemProperty(parsedArgs);
- applyInvokeWithSystemProperty(parsedArgs);
- int[][] rlimits = null;
- if (parsedArgs.rlimits != null) {
- rlimits = parsedArgs.rlimits.toArray(intArray2d);
- }
- if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {
- FileDescriptor[] pipeFds = Libcore.os.pipe();
- childPipeFd = pipeFds[1];
- serverPipeFd = pipeFds[0];
- ZygoteInit.setCloseOnExec(serverPipeFd, true);
- }
- //创建子进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中返回,
- //即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。
- pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
- } catch (IOException ex) {
- logAndPrintError(newStderr, "Exception creating pipe", ex);
- } catch (ErrnoException ex) {
- logAndPrintError(newStderr, "Exception creating pipe", ex);
- } catch (IllegalArgumentException ex) {
- logAndPrintError(newStderr, "Invalid zygote arguments", ex);
- } catch (ZygoteSecurityException ex) {
- logAndPrintError(newStderr,
- "Zygote security policy prevents request: ", ex);
- }
- try {
- //父子进程运行分界线
- if (pid == 0) {
- //子进程执行过程
- IoUtils.closeQuietly(serverPipeFd);
- serverPipeFd = null;
- handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
- // should never get here, the child is expected to either
- // throw ZygoteInit.MethodAndArgsCaller or exec().
- return true;
- } else {
- //父进程,也就是Zygote进程执行过程
- IoUtils.closeQuietly(childPipeFd);
- childPipeFd = null;
- return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
- }
- } finally {
- IoUtils.closeQuietly(childPipeFd);
- IoUtils.closeQuietly(serverPipeFd);
- }
- }
frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
- private boolean handleParentProc(int pid,
- FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {
- if (pid > 0) {
- setChildPgid(pid);
- }
- if (descriptors != null) {
- for (FileDescriptor fd: descriptors) {
- IoUtils.closeQuietly(fd);
- }
- }
- boolean usingWrapper = false;
- if (pipeFd != null && pid > 0) {
- DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));
- int innerPid = -1;
- try {
- innerPid = is.readInt();
- } catch (IOException ex) {
- Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
- } finally {
- try {
- is.close();
- } catch (IOException ex) {
- }
- }
- // Ensure that the pid reported by the wrapped process is either the
- // child process that we forked, or a descendant of it.
- if (innerPid > 0) {
- int parentPid = innerPid;
- while (parentPid > 0 && parentPid != pid) {
- parentPid = Process.getParentPid(parentPid);
- }
- if (parentPid > 0) {
- Log.i(TAG, "Wrapped process has pid " + innerPid);
- pid = innerPid;
- usingWrapper = true;
- } else {
- Log.w(TAG, "Wrapped process reported a pid that is not a child of "
- + "the process that we forked: childPid=" + pid
- + " innerPid=" + innerPid);
- }
- }
- }
- //将创建的应用程序进程ID返回给SystemServer进程的ActivityManagerService服务
- try {
- mSocketOutStream.writeInt(pid);
- mSocketOutStream.writeBoolean(usingWrapper);
- } catch (IOException ex) {
- Log.e(TAG, "Error reading from command socket", ex);
- return true;
- }
- /*
- * If the peer wants to use the socket to wait on the
- * newly spawned process, then we're all done.
- */
- if (parsedArgs.peerWait) {
- try {
- mSocket.close();
- } catch (IOException ex) {
- Log.e(TAG, "Zygote: error closing sockets", ex);
- }
- return true;
- }
- return false;
- }
Zygote孵化出新的应用程序进程后,新的应用程序进程将执行handleChildProc函数,从此与其父进程Zygote分道扬镳。
frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
- private void handleChildProc(Arguments parsedArgs,
- FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
- throws ZygoteInit.MethodAndArgsCaller {
- /*
- * Close the socket, unless we're in "peer wait" mode, in which
- * case it's used to track the liveness of this process.
- */
- if (parsedArgs.peerWait) {
- try {
- ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true);
- sPeerWaitSocket = mSocket;
- } catch (IOException ex) {
- Log.e(TAG, "Zygote Child: error setting peer wait "
- + "socket to be close-on-exec", ex);
- }
- } else {//关闭从Zygote进程复制过来的Socket连接
- closeSocket();
- ZygoteInit.closeServerSocket();
- }
- if (descriptors != null) {
- try {
- //为新创建的应用程序进程重新打开标准输入输出控制台
- ZygoteInit.reopenStdio(descriptors[0],descriptors[1], descriptors[2]);
- for (FileDescriptor fd: descriptors) {
- IoUtils.closeQuietly(fd);
- }
- newStderr = System.err;
- } catch (IOException ex) {
- Log.e(TAG, "Error reopening stdio", ex);
- }
- }
- //设置新进程名称
- if (parsedArgs.niceName != null) {
- Process.setArgV0(parsedArgs.niceName);
- }
- //重新初始化Runtime
- if (parsedArgs.runtimeInit) {
- if (parsedArgs.invokeWith != null) {
- WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, parsedArgs.targetSdkVersion,
- pipeFd, parsedArgs.remainingArgs);
- } else {
- //为应用程序进程启动Binder线程池
- RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);
- }
- } else {
- String className;
- try {
- //读取新进程执行的类名,在Process.start()函数中,传过来的类名为:"android.app.ActivityThread"
- className = parsedArgs.remainingArgs[0];
- } catch (ArrayIndexOutOfBoundsException ex) {
- logAndPrintError(newStderr,"Missing required class name argument", null);
- return;
- }
- 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();
- }
- //加载并执行"android.app.ActivityThread"类
- try {
- ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
- } catch (RuntimeException ex) {
- logAndPrintError(newStderr, "Error starting.", ex);
- }
- }
- }
- }
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
- public static final void zygoteInit(int targetSdkVersion, String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
- //重定向Log输出流
- redirectLogStreams();
- //初始化运行环境
- commonInit();
- //启动Binder线程池
- nativeZygoteInit();
- //调用程序入口函数
- applicationInit(targetSdkVersion, argv);
- }
- /**
- * Redirect System.out and System.err to the Android log.
- */
- public static void redirectLogStreams() {
- System.out.close();
- System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
- System.err.close();
- System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
- }
2.初始化运行环境
- private static final void commonInit() {
- if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
- /* set default handler; this applies to all threads in the VM */
- Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
- /*
- * Install a TimezoneGetter subclass for ZoneInfo.db
- */
- TimezoneGetter.setInstance(new TimezoneGetter() {
- @Override
- public String getId() {
- return SystemProperties.get("persist.sys.timezone");
- }
- });
- TimeZone.setDefault(null);
- /*
- * Sets handler for java.util.logging to use Android log facilities.
- * The odd "new instance-and-then-throw-away" is a mirror of how
- * the "java.util.logging.config.class" system property works. We
- * can't use the system property here since the logger has almost
- * certainly already been initialized.
- */
- LogManager.getLogManager().reset();
- new AndroidConfig();
- /*
- * Sets the default HTTP User-Agent used by HttpURLConnection.
- */
- String userAgent = getDefaultUserAgent();
- System.setProperty("http.agent", userAgent);
- /*
- * Wire socket tagging to traffic stats.
- */
- NetworkManagementSocketTagger.install();
- /*
- * If we're running in an emulator launched with "-trace", put the
- * VM into emulator trace profiling mode so that the user can hit
- * F9/F10 at any time to capture traces. This has performance
- * consequences, so it's not something you want to do always.
- */
- String trace = SystemProperties.get("ro.kernel.android.tracing");
- if (trace.equals("1")) {
- Slog.i(TAG, "NOTE: emulator trace profiling enabled");
- Debug.enableEmulatorTraceOutput();
- }
- initialized = true;
- }
3.启动Binder线程池
关于Binder线程池的启动过程请参考Android应用程序启动Binder线程源码分析
4.调用进程入口函数
- static void invokeStaticMain(ClassLoader loader,
- String className, String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- //加载"android.app.ActivityThread"类
- Class<?> cl;
- try {
- cl = loader.loadClass(className);
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Missing class when invoking static main " + className,
- ex);
- }
- //通过类反射机制查找ActivityThread类中的main函数
- 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);
- }
- //获取main函数的修饰符
- int modifiers = m.getModifiers();
- //进程入口函数必须为静态Public类型
- 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);
- }
抛出MethodAndArgsCaller异常,并在ZygoteInit.main()函数中捕获该异常,这样就可以清除应用程序进程创建过程的调用栈,将应用程序启动的入口函数设置为ActivityThread.main()
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
- public static void main(String argv[]) {
- try {
- ...
- //捕获MethodAndArgsCaller异常
- } catch (MethodAndArgsCaller caller) {
- caller.run();
- } catch (RuntimeException ex) {
- Log.e(TAG, "Zygote died with exception", ex);
- closeServerSocket();
- throw ex;
- }
- }
- public static class MethodAndArgsCaller extends Exception implements Runnable {
- public void run() {
- try {
- mMethod.invoke(null, new Object[] { mArgs });
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
- } catch (InvocationTargetException ex) {
- Throwable cause = ex.getCause();
- if (cause instanceof RuntimeException) {
- throw (RuntimeException) cause;
- } else if (cause instanceof Error) {
- throw (Error) cause;
- }
- throw new RuntimeException(ex);
- }
- }
- }
frameworks\base\core\java\android\app\ActivityThread.java
- public static void main(String[] args) {
- SamplingProfilerIntegration.start();
- // CloseGuard defaults to true and can be quite spammy. We
- // disable it here, but selectively enable it later (via
- // StrictMode) on debug builds, but using DropBox, not logs.
- CloseGuard.setEnabled(false);
- Process.setArgV0("<pre-initialized>");
- //为新的应用程序创建消息队列
- Looper.prepareMainLooper();
- if (sMainThreadHandler == null) {
- sMainThreadHandler = new Handler();
- }
- //创建一个ActivityThread对象,初始化应用程序运行环境,每一个进程对应一个ActivityThread实例
- ActivityThread thread = new ActivityThread();
- //建立与ActivityManagerService之间的Binder通信通道
- thread.attach(false);
- AsyncTask.init();
- if (false) {
- Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));
- }
- //为新的应用程序进程启动消息循环,这个消息循环就是应用程序主线程消息循环
- Looper.loop();
- throw new RuntimeException("Main thread loop unexpectedly exited");
- }
至此,Android应用程序进程启动过程的源代码就分析完成了,以下是android应用进程的启动过程的时序图: