Android 应用程序进程启动过程源码分析 .

在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

  1. final ProcessRecord startProcessLocked(String processName,  
  2.         ApplicationInfo info, boolean knownToBeDead, int intentFlags,  
  3.         String hostingType, ComponentName hostingName, boolean allowWhileBooting,  
  4.         boolean isolated) {  
  5.     ProcessRecord app;  
  6.     //是否在现有进程中启动   
  7.     if (!isolated) {  
  8.         //从现有进程表mProcessNames中查找相应的进程描述符ProcessRecord   
  9.         app = getProcessRecordLocked(processName, info.uid);  
  10.     } else {  
  11.         // If this is an isolated process, it can't re-use an existing process.   
  12.         app = null;  
  13.     }  
  14.     // We don't have to do anything more if:   
  15.     // (1) There is an existing application record; and   
  16.     // (2) The caller doesn't think it is dead, OR there is no thread   
  17.     //     object attached to it so we know it couldn't have crashed; and   
  18.     // (3) There is a pid assigned to it, so it is either starting or   
  19.     //     already running.   
  20.     if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName  
  21.             + " app=" + app + " knownToBeDead=" + knownToBeDead  
  22.             + " thread=" + (app != null ? app.thread : null)  
  23.             + " pid=" + (app != null ? app.pid : -1));  
  24.     if (app != null && app.pid > 0) {  
  25.         if (!knownToBeDead || app.thread == null) {  
  26.             // We already have the app running, or are waiting for it to   
  27.             // come up (we have a pid but not yet its thread), so keep it.   
  28.             if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);  
  29.             // If this is a new package in the process, add the package to the list   
  30.             app.addPackage(info.packageName);  
  31.             return app;  
  32.         } else {  
  33.             // An application record is attached to a previous process,   
  34.             // clean it up now.   
  35.             if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);  
  36.             handleAppDiedLocked(app, truetrue);  
  37.         }  
  38.     }  
  39.     String hostingNameStr = hostingName != null  
  40.             ? hostingName.flattenToShortString() : null;  
  41.     if (!isolated) {  
  42.         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {  
  43.             // If we are in the background, then check to see if this process   
  44.             // is bad.  If so, we will just silently fail.   
  45.             if (mBadProcesses.get(info.processName, info.uid) != null) {  
  46.                 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid  
  47.                         + "/" + info.processName);  
  48.                 return null;  
  49.             }  
  50.         } else {  
  51.             // When the user is explicitly starting a process, then clear its   
  52.             // crash count so that we won't make it bad until they see at   
  53.             // least one crash dialog again, and make the process good again   
  54.             // if it had been bad.   
  55.             if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid  
  56.                     + "/" + info.processName);  
  57.             mProcessCrashTimes.remove(info.processName, info.uid);  
  58.             if (mBadProcesses.get(info.processName, info.uid) != null) {  
  59.                 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,info.processName);  
  60.                 mBadProcesses.remove(info.processName, info.uid);  
  61.                 if (app != null) {  
  62.                     app.bad = false;  
  63.                 }  
  64.             }  
  65.         }  
  66.     }  
  67.   
  68.     if (app == null) {  
  69.         //在ActivityManagerService中为新进程创建一个ProcessRecord实例   
  70.         app = newProcessRecordLocked(null, info, processName, isolated);  
  71.         if (app == null) {  
  72.             Slog.w(TAG, "Failed making new process record for "  
  73.                     + processName + "/" + info.uid + " isolated=" + isolated);  
  74.             return null;  
  75.         }  
  76.         //添加到进程列表中   
  77.         mProcessNames.put(processName, app.uid, app);  
  78.         //如果当前服务运行在独立进程中,添加到独立进程表mIsolatedProcesses中   
  79.         /** 
  80.          * SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 
  81.          * The currently running isolated processes. 
  82.          */  
  83.         if (isolated) {  
  84.             mIsolatedProcesses.put(app.uid, app);  
  85.         }  
  86.     } else {  
  87.         // If this is a new package in the process, add the package to the list   
  88.         app.addPackage(info.packageName);  
  89.     }  
  90.     // If the system is not ready yet, then hold off on starting this   
  91.     // process until it is.   
  92.     if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) {  
  93.         /** 
  94.          * final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 
  95.          * List of records for processes that someone had tried to start before the 
  96.          * system was ready.  We don't start them at that point, but ensure they 
  97.          * are started by the time booting is complete. 
  98.          */  
  99.         if (!mProcessesOnHold.contains(app)) {  
  100.             mProcessesOnHold.add(app);  
  101.         }  
  102.         if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);  
  103.         return app;  
  104.     }  
  105.     //调用startProcessLocked启动新的应用程序进程   
  106.     startProcessLocked(app, hostingType, hostingNameStr);  
  107.     return (app.pid != 0) ? app : null;  
  108. }  
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;
}
在该函数里,首先在ActivityManagerService中为即将创建的新应用程序进程创建一个ProcessRecord对象,并保存到mProcessNames进程列表中,然后调用另一个重载函数startProcessLocked来请求创建一个新的应用程序进程。

frameworks\base\services\java\com\android\server\am\ActivityManagerService.java

  1. private final void startProcessLocked(ProcessRecord app,  
  2.         String hostingType, String hostingNameStr) {  
  3.     if (app.pid > 0 && app.pid != MY_PID) {  
  4.         synchronized (mPidsSelfLocked) {  
  5.             mPidsSelfLocked.remove(app.pid);  
  6.             mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);  
  7.         }  
  8.         app.pid = 0;  
  9.     }  
  10.     //系统准备好了,马上启动服务,因此如果mProcessesOnHold列表中包含当前启动的服务,则需移除   
  11.     if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,  
  12.             "startProcessLocked removing on hold: " + app);  
  13.     mProcessesOnHold.remove(app);  
  14.     //唤醒进程信息收集线程   
  15.     updateCpuStats();  
  16.     System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);  
  17.     mProcDeaths[0] = 0;  
  18.     try {  
  19.         int uid = app.uid;  
  20.         int[] gids = null;  
  21.         if (!app.isolated) {  
  22.             try {  
  23.                 gids = mContext.getPackageManager().getPackageGids(  
  24.                         app.info.packageName);  
  25.             } catch (PackageManager.NameNotFoundException e) {  
  26.                 Slog.w(TAG, "Unable to retrieve gids", e);  
  27.             }  
  28.         }  
  29.         if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {  
  30.             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL  
  31.                     && mTopComponent != null  
  32.                     && app.processName.equals(mTopComponent.getPackageName())) {  
  33.                 uid = 0;  
  34.             }  
  35.             if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL  
  36.                     && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {  
  37.                 uid = 0;  
  38.             }  
  39.         }  
  40.         //设置应用程序进程创建方式   
  41.         int debugFlags = 0;  
  42.         if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {  
  43.             debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;  
  44.             // Also turn on CheckJNI for debuggable apps. It's quite   
  45.             // awkward to turn on otherwise.   
  46.             debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;  
  47.         }  
  48.         // Run the app in safe mode if its manifest requests so or the   
  49.         // system is booted in safe mode.   
  50.         if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||  
  51.             Zygote.systemInSafeMode == true) {  
  52.             debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;  
  53.         }  
  54.         if ("1".equals(SystemProperties.get("debug.checkjni"))) {  
  55.             debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;  
  56.         }  
  57.         if ("1".equals(SystemProperties.get("debug.jni.logging"))) {  
  58.             debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;  
  59.         }  
  60.         if ("1".equals(SystemProperties.get("debug.assert"))) {  
  61.             debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;  
  62.         }  
  63.         //它调用了Process.start函数开始为应用程序创建新的进程,   
  64.         //它传入一个第一个参数为"android.app.ActivityThread",这就是进程初始化时要加载的Java类了,   
  65.         //把这个类加载到进程之后,就会把它里面的静态成员函数main作为进程的入口点,   
  66.         Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",  
  67.                 app.processName, uid, uid, gids, debugFlags,  
  68.                 app.info.targetSdkVersion, null);  
  69.         BatteryStatsImpl bs = app.batteryStats.getBatteryStats();  
  70.         synchronized (bs) {  
  71.             if (bs.isOnBattery()) {  
  72.                 app.batteryStats.incStartsLocked();  
  73.             }  
  74.         }  
  75.         EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,  
  76.                 app.processName, hostingType,  
  77.                 hostingNameStr != null ? hostingNameStr : "");  
  78.         //如果启动的进程是一个持久进程,则添加到Watchdog中监控   
  79.         if (app.persistent) {  
  80.             Watchdog.getInstance().processStarted(app.processName, startResult.pid);  
  81.         }  
  82.         StringBuilder buf = mStringBuilder;  
  83.         buf.setLength(0);  
  84.         buf.append("Start proc ");  
  85.         buf.append(app.processName);  
  86.         buf.append(" for ");  
  87.         buf.append(hostingType);  
  88.         if (hostingNameStr != null) {  
  89.             buf.append(" ");  
  90.             buf.append(hostingNameStr);  
  91.         }  
  92.         buf.append(": pid=");  
  93.         buf.append(startResult.pid);  
  94.         buf.append(" uid=");  
  95.         buf.append(uid);  
  96.         buf.append(" gids={");  
  97.         if (gids != null) {  
  98.             for (int gi=0; gi<gids.length; gi++) {  
  99.                 if (gi != 0) buf.append(", ");  
  100.                 buf.append(gids[gi]);  
  101.   
  102.             }  
  103.         }  
  104.         buf.append("}");  
  105.         Slog.i(TAG, buf.toString());  
  106.         app.pid = startResult.pid;  
  107.         app.usingWrapper = startResult.usingWrapper;  
  108.         app.removed = false;  
  109.         //将新创建的进程描述符ProcessRecord保存到mPidsSelfLocked链表中   
  110.         /** 
  111.         * final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 
  112.         * All of the processes we currently have running organized by pid. 
  113.         * The keys are the pid running the application. 
  114.         */  
  115.         synchronized (mPidsSelfLocked) {  
  116.             this.mPidsSelfLocked.put(startResult.pid, app);  
  117.             Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);  
  118.             msg.obj = app;  
  119.             mHandler.sendMessageDelayed(msg, startResult.usingWrapper  
  120.                     ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);  
  121.         }  
  122.     } catch (RuntimeException e) {  
  123.         // XXX do better error recovery.   
  124.         app.pid = 0;  
  125.         Slog.e(TAG, "Failure starting process " + app.processName, e);  
  126.     }  
  127.     if (LC_RAM_SUPPORT  
  128.             && ((app.info.flags & (ApplicationInfo.FLAG_SYSTEM)) == (ApplicationInfo.FLAG_SYSTEM))  
  129.             && (CONTACTS_PROCESS_NAME.equals(app.processName))) {  
  130.         app.isContactsProcess = true;  
  131.     }  
  132.     if (LC_RAM_SUPPORT && fixAdjList.containsKey(app.processName)) {  
  133.         app.fixAdj = fixAdjList.get(app.processName);  
  134.         Slog.v(TAG, "app[" + app.processName + "] has fix adj:" + app.fixAdj);  
  135.     }  
  136. }  
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);
	}
}
在该函数里,首先获取即将创建的应用程序的gid和uid,并设置应用程序进程创建方式,然后调用Process类的start()函数来创建一个新的应用程序进程,同时指定新进程执行的入口为ActivityThread类的main函数。
frameworks\base\core\java\android\os\Process.java
  1. public static final ProcessStartResult start(final String processClass,  
  2.                               final String niceName,  
  3.                               int uid, int gid, int[] gids,  
  4.                               int debugFlags, int targetSdkVersion,  
  5.                               String[] zygoteArgs) {  
  6.     try {  
  7.         return startViaZygote(processClass, niceName, uid, gid, gids,  
  8.                 debugFlags, targetSdkVersion, zygoteArgs);  
  9.     } catch (ZygoteStartFailedEx ex) {  
  10.         Log.e(LOG_TAG,"Starting VM process through Zygote failed");  
  11.         throw new RuntimeException("Starting VM process through Zygote failed", ex);  
  12.     }  
  13. }  
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);
	}
}
该函数直接调用startViaZygote()函数来创建一个新的应用程序进程。

frameworks\base\core\java\android\os\Process.java

  1. private static ProcessStartResult startViaZygote(final String processClass,  
  2.                               final String niceName,  
  3.                               final int uid, final int gid,  
  4.                               final int[] gids,  
  5.                               int debugFlags, int targetSdkVersion,  
  6.                               String[] extraArgs)  
  7.                               throws ZygoteStartFailedEx {  
  8.     synchronized(Process.class) {  
  9.         ArrayList<String> argsForZygote = new ArrayList<String>();  
  10.         // --runtime-init, --setuid=, --setgid=,   
  11.         // and --setgroups= must go first   
  12.         argsForZygote.add("--runtime-init");  
  13.         argsForZygote.add("--setuid=" + uid);  
  14.         argsForZygote.add("--setgid=" + gid);  
  15.         if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {  
  16.             argsForZygote.add("--enable-jni-logging");  
  17.         }  
  18.         if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {  
  19.             argsForZygote.add("--enable-safemode");  
  20.         }  
  21.         if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {  
  22.             argsForZygote.add("--enable-debugger");  
  23.         }  
  24.         if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {  
  25.             argsForZygote.add("--enable-checkjni");  
  26.         }  
  27.         if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {  
  28.             argsForZygote.add("--enable-assert");  
  29.         }  
  30.         argsForZygote.add("--target-sdk-version=" + targetSdkVersion);  
  31.         //TODO optionally enable debuger   
  32.         //argsForZygote.add("--enable-debugger");   
  33.         // --setgroups is a comma-separated list   
  34.         if (gids != null && gids.length > 0) {  
  35.             StringBuilder sb = new StringBuilder();  
  36.             sb.append("--setgroups=");  
  37.             int sz = gids.length;  
  38.             for (int i = 0; i < sz; i++) {  
  39.                 if (i != 0) {  
  40.                     sb.append(',');  
  41.                 }  
  42.                 sb.append(gids[i]);  
  43.             }  
  44.             argsForZygote.add(sb.toString());  
  45.         }  
  46.         if (niceName != null) {  
  47.             argsForZygote.add("--nice-name=" + niceName);  
  48.         }  
  49.         argsForZygote.add(processClass);  
  50.         if (extraArgs != null) {  
  51.             for (String arg : extraArgs) {  
  52.                 argsForZygote.add(arg);  
  53.             }  
  54.         }  
  55.         //将通过Socket方式将参数列表发送给Zygote进程   
  56.         return zygoteSendArgsAndGetResult(argsForZygote);  
  57.     }  
  58. }  
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);
	}
}
在该函数里,首先将新的应用程序进程启动参数保存到argsForZygote列表中,然后调用zygoteSendArgsAndGetPid将应用程序进程启动参数发送到Zygote进程。
frameworks\base\core\java\android\os\Process.java
  1. private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)  
  2.         throws ZygoteStartFailedEx {  
  3.     //创建一个客户端Socket,并连接到Zygote进程的Socket服务端   
  4.     openZygoteSocketIfNeeded();  
  5.     try {  
  6.         /** 
  7.          * See com.android.internal.os.ZygoteInit.readArgumentList() 
  8.          * Presently the wire format to the zygote process is: 
  9.          * a) a count of arguments (argc, in essence) 
  10.          * b) a number of newline-separated argument strings equal to count 
  11.          * 
  12.          * After the zygote process reads these it will write the pid of 
  13.          * the child or -1 on failure, followed by boolean to 
  14.          * indicate whether a wrapper process was used. 
  15.          */  
  16.         //将应用程序启动参数列表写入到Socket   
  17.         sZygoteWriter.write(Integer.toString(args.size()));  
  18.         sZygoteWriter.newLine();  
  19.         int sz = args.size();  
  20.         for (int i = 0; i < sz; i++) {  
  21.             String arg = args.get(i);  
  22.             if (arg.indexOf('\n') >= 0) {  
  23.                 throw new ZygoteStartFailedEx(  
  24.                         "embedded newlines not allowed");  
  25.             }  
  26.             sZygoteWriter.write(arg);  
  27.             sZygoteWriter.newLine();  
  28.         }  
  29.         sZygoteWriter.flush();  
  30.         //读取Zygote进程返回来的结果   
  31.         ProcessStartResult result = new ProcessStartResult();  
  32.         result.pid = sZygoteInputStream.readInt();  
  33.         if (result.pid < 0) {  
  34.             throw new ZygoteStartFailedEx("fork() failed");  
  35.         }  
  36.         result.usingWrapper = sZygoteInputStream.readBoolean();  
  37.         return result;  
  38.     } catch (IOException ex) {  
  39.         try {  
  40.             if (sZygoteSocket != null) {  
  41.                 sZygoteSocket.close();  
  42.             }  
  43.         } catch (IOException ex2) {  
  44.             // we're going to fail anyway   
  45.             Log.e(LOG_TAG,"I/O exception on routine close", ex2);  
  46.         }  
  47.         sZygoteSocket = null;  
  48.         throw new ZygoteStartFailedEx(ex);  
  49.     }  
  50. }  
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);
	}
}
该函数首先在SystemServer进程中创建一个客户端LocalSocket,并连接到Zygote进程的名为"zygote"的服务端Socket

  1. private static void openZygoteSocketIfNeeded()   
  2.         throws ZygoteStartFailedEx {  
  3.     int retryCount;  
  4.     if (sPreviousZygoteOpenFailed) {  
  5.         /* 
  6.          * If we've failed before, expect that we'll fail again and 
  7.          * don't pause for retries. 
  8.          */  
  9.         retryCount = 0;  
  10.     } else {  
  11.         retryCount = 10;              
  12.     }  
  13.   
  14.     /* 
  15.      * See bug #811181: Sometimes runtime can make it up before zygote. 
  16.      * Really, we'd like to do something better to avoid this condition, 
  17.      * but for now just wait a bit... 
  18.      */  
  19.     for (int retry = 0; (sZygoteSocket == null) && (retry < (retryCount + 1)); retry++ ) {  
  20.         if (retry > 0) {  
  21.             try {  
  22.                 Log.i("Zygote""Zygote not up yet, sleeping...");  
  23.                 Thread.sleep(ZYGOTE_RETRY_MILLIS);  
  24.             } catch (InterruptedException ex) {  
  25.                 // should never happen   
  26.             }  
  27.         }  
  28.         try {  
  29.             sZygoteSocket = new LocalSocket();  
  30.             //连接到Zygote进程的服务端zygote Socket   
  31.             sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, LocalSocketAddress.Namespace.RESERVED));  
  32.             sZygoteInputStream = new DataInputStream(sZygoteSocket.getInputStream());  
  33.             sZygoteWriter = new BufferedWriter(new OutputStreamWriter(  
  34.                                 sZygoteSocket.getOutputStream()),256);  
  35.             Log.i("Zygote""Process: zygote socket opened");  
  36.             sPreviousZygoteOpenFailed = false;  
  37.             break;  
  38.         } catch (IOException ex) {  
  39.             //Socket操作失败,关闭该Socket   
  40.             if (sZygoteSocket != null) {  
  41.                 try {  
  42.                     sZygoteSocket.close();  
  43.                 } catch (IOException ex2) {  
  44.                     Log.e(LOG_TAG,"I/O exception on close after exception",ex2);  
  45.                 }  
  46.             }  
  47.             sZygoteSocket = null;  
  48.         }  
  49.     }  
  50.   
  51.     if (sZygoteSocket == null) {  
  52.         sPreviousZygoteOpenFailed = true;  
  53.         throw new ZygoteStartFailedEx("connect failed");                   
  54.     }  
  55. }  
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");                 
	}
}
最后将参数列表写入到创建的客户端Socket中,从而将应用程序启动参数发送给Zygote进程,启动参数包括:

"--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进程孵化应用程序进程


ActivityManagerService通过Socket方式将请求参数发送给Zygote,此时Zygote正在runSelectLoopMode()函数中监听Socket连接。

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

  1. private static void runSelectLoopMode() throws MethodAndArgsCaller {  
  2.     ArrayList<FileDescriptor> fds = new ArrayList();  
  3.     ArrayList<ZygoteConnection> peers = new ArrayList();  
  4.     FileDescriptor[] fdArray = new FileDescriptor[4];  
  5.       
  6.     fds.add(sServerSocket.getFileDescriptor());  
  7.     peers.add(null);  
  8.   
  9.     int loopCount = GC_LOOP_COUNT;  
  10.     while (true) {  
  11.         int index;  
  12.         /* 
  13.          * Call gc() before we block in select(). 
  14.          * It's work that has to be done anyway, and it's better 
  15.          * to avoid making every child do it.  It will also 
  16.          * madvise() any free memory as a side-effect. 
  17.          * 
  18.          * Don't call it every time, because walking the entire 
  19.          * heap is a lot of overhead to free a few hundred bytes. 
  20.          */  
  21.         if (loopCount <= 0) {  
  22.             gc();  
  23.             loopCount = GC_LOOP_COUNT;  
  24.         } else {  
  25.             loopCount--;  
  26.         }  
  27.         try {  
  28.             fdArray = fds.toArray(fdArray);  
  29.             //监听zygote Socket是否有客户端连接   
  30.             index = selectReadable(fdArray);  
  31.         } catch (IOException ex) {  
  32.             throw new RuntimeException("Error in select()", ex);  
  33.         }  
  34.         if (index < 0) {  
  35.             throw new RuntimeException("Error in select()");  
  36.         //zygote socket句柄中有事件到来,表示有客户端的socket连接   
  37.         } else if (index == 0) {  
  38.             //接收客户端连接请求,并将客户端请求添加到句柄池中监控   
  39.             ZygoteConnection newPeer = acceptCommandPeer();  
  40.             peers.add(newPeer);  
  41.             fds.add(newPeer.getFileDesciptor());  
  42.         //客户端连接Socket有事件到来,表示SystemServer进程正在发送应用程序启动参数   
  43.         } else {  
  44.             boolean done;  
  45.             //孵化一个新的应用程序进程   
  46.             done = peers.get(index).runOnce();  
  47.             //从socket句柄池中移除客户连接socket句柄   
  48.             if (done) {  
  49.                 peers.remove(index);  
  50.                 fds.remove(index);  
  51.             }  
  52.         }  
  53.     }  
  54. }  
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);
			}
		}
	}
}
当接收到新的客户端socket连接请求时,函数从selectReadable中返回,并为该客户端连接创建一个ZygoteConnection实例;当Zygote接收到SystemServer进程发送过来的应用程序进程启动参数时,就会调用相应ZygoteConnection实例的runOnce()函数来启动一个新的进程。

frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java

  1. boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {  
  2.   
  3.     String args[];  
  4.     Arguments parsedArgs = null;  
  5.     FileDescriptor[] descriptors;  
  6.     try {  
  7.         //读取参数   
  8.         args = readArgumentList();  
  9.         descriptors = mSocket.getAncillaryFileDescriptors();  
  10.     } catch (IOException ex) {  
  11.         Log.w(TAG, "IOException on command socket " + ex.getMessage());  
  12.         closeSocket();  
  13.         return true;  
  14.     }  
  15.     if (args == null) {  
  16.         // EOF reached.   
  17.         closeSocket();  
  18.         return true;  
  19.     }  
  20.     /** the stderr of the most recent request, if avail */  
  21.     PrintStream newStderr = null;  
  22.   
  23.     if (descriptors != null && descriptors.length >= 3) {  
  24.         newStderr = new PrintStream(new FileOutputStream(descriptors[2]));  
  25.     }  
  26.     int pid = -1;  
  27.     FileDescriptor childPipeFd = null;  
  28.     FileDescriptor serverPipeFd = null;  
  29.     try {  
  30.         parsedArgs = new Arguments(args);  
  31.         applyUidSecurityPolicy(parsedArgs, peer);  
  32.         applyRlimitSecurityPolicy(parsedArgs, peer);  
  33.         applyCapabilitiesSecurityPolicy(parsedArgs, peer);  
  34.         applyInvokeWithSecurityPolicy(parsedArgs, peer);  
  35.         applyDebuggerSystemProperty(parsedArgs);  
  36.         applyInvokeWithSystemProperty(parsedArgs);  
  37.         int[][] rlimits = null;  
  38.   
  39.         if (parsedArgs.rlimits != null) {  
  40.             rlimits = parsedArgs.rlimits.toArray(intArray2d);  
  41.         }  
  42.   
  43.         if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {  
  44.             FileDescriptor[] pipeFds = Libcore.os.pipe();  
  45.             childPipeFd = pipeFds[1];  
  46.             serverPipeFd = pipeFds[0];  
  47.             ZygoteInit.setCloseOnExec(serverPipeFd, true);  
  48.         }  
  49.         //创建子进程,而且有两个返回值,一个是在当前进程中返回的,一个是在新创建的进程中返回,   
  50.         //即在当前进程的子进程中返回,在当前进程中的返回值就是新创建的子进程的pid值,而在子进程中的返回值是0。   
  51.         pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,  
  52.                 parsedArgs.gids, parsedArgs.debugFlags, rlimits);  
  53.     } catch (IOException ex) {  
  54.         logAndPrintError(newStderr, "Exception creating pipe", ex);  
  55.     } catch (ErrnoException ex) {  
  56.         logAndPrintError(newStderr, "Exception creating pipe", ex);  
  57.     } catch (IllegalArgumentException ex) {  
  58.         logAndPrintError(newStderr, "Invalid zygote arguments", ex);  
  59.     } catch (ZygoteSecurityException ex) {  
  60.         logAndPrintError(newStderr,  
  61.                 "Zygote security policy prevents request: ", ex);  
  62.     }  
  63.     try {  
  64.         //父子进程运行分界线   
  65.         if (pid == 0) {  
  66.             //子进程执行过程   
  67.             IoUtils.closeQuietly(serverPipeFd);  
  68.             serverPipeFd = null;  
  69.             handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);  
  70.             // should never get here, the child is expected to either   
  71.             // throw ZygoteInit.MethodAndArgsCaller or exec().   
  72.             return true;  
  73.         } else {  
  74.             //父进程,也就是Zygote进程执行过程   
  75.             IoUtils.closeQuietly(childPipeFd);  
  76.             childPipeFd = null;  
  77.             return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);  
  78.         }  
  79.     } finally {  
  80.         IoUtils.closeQuietly(childPipeFd);  
  81.         IoUtils.closeQuietly(serverPipeFd);  
  82.     }  
  83. }  
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);
	}
}
函数首先调用readArgumentList读取ActivityManagerService发送过来的应用程序启动参数,接着根据参数调用forkAndSpecialize函数fork一个新的应用程序进程,就是复制一份Zygote进程地址空间,当返回的pid=0时,表示当前是新创建的应用程序进程,否则为Zygote进程的函数执行返回。首先来分析Zygote进程返回后执行的工作:

frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java

  1. private boolean handleParentProc(int pid,  
  2.         FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {  
  3.     if (pid > 0) {  
  4.         setChildPgid(pid);  
  5.     }  
  6.     if (descriptors != null) {  
  7.         for (FileDescriptor fd: descriptors) {  
  8.             IoUtils.closeQuietly(fd);  
  9.         }  
  10.     }  
  11.     boolean usingWrapper = false;  
  12.     if (pipeFd != null && pid > 0) {  
  13.         DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));  
  14.         int innerPid = -1;  
  15.         try {  
  16.             innerPid = is.readInt();  
  17.         } catch (IOException ex) {  
  18.             Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);  
  19.         } finally {  
  20.             try {  
  21.                 is.close();  
  22.             } catch (IOException ex) {  
  23.             }  
  24.         }  
  25.         // Ensure that the pid reported by the wrapped process is either the   
  26.         // child process that we forked, or a descendant of it.   
  27.         if (innerPid > 0) {  
  28.             int parentPid = innerPid;  
  29.             while (parentPid > 0 && parentPid != pid) {  
  30.                 parentPid = Process.getParentPid(parentPid);  
  31.             }  
  32.             if (parentPid > 0) {  
  33.                 Log.i(TAG, "Wrapped process has pid " + innerPid);  
  34.                 pid = innerPid;  
  35.                 usingWrapper = true;  
  36.             } else {  
  37.                 Log.w(TAG, "Wrapped process reported a pid that is not a child of "  
  38.                         + "the process that we forked: childPid=" + pid  
  39.                         + " innerPid=" + innerPid);  
  40.             }  
  41.         }  
  42.     }  
  43.     //将创建的应用程序进程ID返回给SystemServer进程的ActivityManagerService服务   
  44.     try {  
  45.         mSocketOutStream.writeInt(pid);  
  46.         mSocketOutStream.writeBoolean(usingWrapper);  
  47.     } catch (IOException ex) {  
  48.         Log.e(TAG, "Error reading from command socket", ex);  
  49.         return true;  
  50.     }  
  51.     /* 
  52.      * If the peer wants to use the socket to wait on the 
  53.      * newly spawned process, then we're all done. 
  54.      */  
  55.     if (parsedArgs.peerWait) {  
  56.         try {  
  57.             mSocket.close();  
  58.         } catch (IOException ex) {  
  59.             Log.e(TAG, "Zygote: error closing sockets", ex);  
  60.         }  
  61.         return true;  
  62.     }  
  63.     return false;  
  64. }  
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进程将新创建的应用程序进程写回到SystemServer进程后,从函数handleParentProc一路返回到runSelectLoopMode(),继续监听客户端进程的Socket连接请求。


Zygote孵化出新的应用程序进程后,新的应用程序进程将执行handleChildProc函数,从此与其父进程Zygote分道扬镳。

frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java

  1. private void handleChildProc(Arguments parsedArgs,  
  2.         FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)  
  3.         throws ZygoteInit.MethodAndArgsCaller {  
  4.     /* 
  5.      * Close the socket, unless we're in "peer wait" mode, in which 
  6.      * case it's used to track the liveness of this process. 
  7.      */  
  8.   
  9.     if (parsedArgs.peerWait) {  
  10.         try {  
  11.             ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true);  
  12.             sPeerWaitSocket = mSocket;  
  13.         } catch (IOException ex) {  
  14.             Log.e(TAG, "Zygote Child: error setting peer wait "  
  15.                     + "socket to be close-on-exec", ex);  
  16.         }  
  17.     } else {//关闭从Zygote进程复制过来的Socket连接   
  18.         closeSocket();  
  19.         ZygoteInit.closeServerSocket();  
  20.     }  
  21.     if (descriptors != null) {  
  22.         try {  
  23.             //为新创建的应用程序进程重新打开标准输入输出控制台   
  24.             ZygoteInit.reopenStdio(descriptors[0],descriptors[1], descriptors[2]);  
  25.             for (FileDescriptor fd: descriptors) {  
  26.                 IoUtils.closeQuietly(fd);  
  27.             }  
  28.             newStderr = System.err;  
  29.         } catch (IOException ex) {  
  30.             Log.e(TAG, "Error reopening stdio", ex);  
  31.         }  
  32.     }  
  33.     //设置新进程名称   
  34.     if (parsedArgs.niceName != null) {  
  35.         Process.setArgV0(parsedArgs.niceName);  
  36.     }  
  37.     //重新初始化Runtime   
  38.     if (parsedArgs.runtimeInit) {  
  39.         if (parsedArgs.invokeWith != null) {  
  40.             WrapperInit.execApplication(parsedArgs.invokeWith,  
  41.                     parsedArgs.niceName, parsedArgs.targetSdkVersion,  
  42.                     pipeFd, parsedArgs.remainingArgs);  
  43.         } else {  
  44.             //为应用程序进程启动Binder线程池   
  45.             RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remainingArgs);  
  46.         }  
  47.     } else {  
  48.         String className;  
  49.         try {  
  50.             //读取新进程执行的类名,在Process.start()函数中,传过来的类名为:"android.app.ActivityThread"   
  51.             className = parsedArgs.remainingArgs[0];  
  52.         } catch (ArrayIndexOutOfBoundsException ex) {  
  53.             logAndPrintError(newStderr,"Missing required class name argument"null);  
  54.             return;  
  55.         }  
  56.         String[] mainArgs = new String[parsedArgs.remainingArgs.length - 1];  
  57.         System.arraycopy(parsedArgs.remainingArgs, 1,mainArgs, 0, mainArgs.length);  
  58.         if (parsedArgs.invokeWith != null) {  
  59.             WrapperInit.execStandalone(parsedArgs.invokeWith,parsedArgs.classpath, className, mainArgs);  
  60.         } else {  
  61.             //获取类加载器   
  62.             ClassLoader cloader;  
  63.             if (parsedArgs.classpath != null) {  
  64.                 cloader = new PathClassLoader(parsedArgs.classpath,ClassLoader.getSystemClassLoader());  
  65.             } else {  
  66.                 cloader = ClassLoader.getSystemClassLoader();  
  67.             }  
  68.             //加载并执行"android.app.ActivityThread"类   
  69.             try {  
  70.                 ZygoteInit.invokeStaticMain(cloader, className, mainArgs);  
  71.             } catch (RuntimeException ex) {  
  72.                 logAndPrintError(newStderr, "Error starting.", ex);  
  73.             }  
  74.         }  
  75.     }  
  76. }  
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);
			}
		}
	}
}
由于应用程序启动参数中已经设置了"--runtime-init"标志位,因此新创建的应用程序进程将调用RuntimeInit.zygoteInit()函数来初始化运行时库,为应用程序启动Binder线程池,完成这些准备工作后,调用应用程序进程的入口函数ActivityThread.main()为应用程序进程创建消息循环。

frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

  1. public static final void zygoteInit(int targetSdkVersion, String[] argv)  
  2.         throws ZygoteInit.MethodAndArgsCaller {  
  3.     if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");  
  4.     //重定向Log输出流   
  5.     redirectLogStreams();  
  6.     //初始化运行环境   
  7.     commonInit();  
  8.     //启动Binder线程池   
  9.     nativeZygoteInit();  
  10.     //调用程序入口函数   
  11.     applicationInit(targetSdkVersion, argv);  
  12. }  
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);
}
1. 初始化Log输出流

  1. /** 
  2.  * Redirect System.out and System.err to the Android log. 
  3.  */  
  4. public static void redirectLogStreams() {  
  5.     System.out.close();  
  6.     System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));  
  7.     System.err.close();  
  8.     System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));  
  9. }  
/**
 * 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.初始化运行环境

  1. private static final void commonInit() {  
  2.     if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");  
  3.   
  4.     /* set default handler; this applies to all threads in the VM */  
  5.     Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());  
  6.   
  7.     /* 
  8.      * Install a TimezoneGetter subclass for ZoneInfo.db 
  9.      */  
  10.     TimezoneGetter.setInstance(new TimezoneGetter() {  
  11.         @Override  
  12.         public String getId() {  
  13.             return SystemProperties.get("persist.sys.timezone");  
  14.         }  
  15.     });  
  16.     TimeZone.setDefault(null);  
  17.   
  18.     /* 
  19.      * Sets handler for java.util.logging to use Android log facilities. 
  20.      * The odd "new instance-and-then-throw-away" is a mirror of how 
  21.      * the "java.util.logging.config.class" system property works. We 
  22.      * can't use the system property here since the logger has almost 
  23.      * certainly already been initialized. 
  24.      */  
  25.     LogManager.getLogManager().reset();  
  26.     new AndroidConfig();  
  27.   
  28.     /* 
  29.      * Sets the default HTTP User-Agent used by HttpURLConnection. 
  30.      */  
  31.     String userAgent = getDefaultUserAgent();  
  32.     System.setProperty("http.agent", userAgent);  
  33.   
  34.     /* 
  35.      * Wire socket tagging to traffic stats. 
  36.      */  
  37.     NetworkManagementSocketTagger.install();  
  38.   
  39.     /* 
  40.      * If we're running in an emulator launched with "-trace", put the 
  41.      * VM into emulator trace profiling mode so that the user can hit 
  42.      * F9/F10 at any time to capture traces.  This has performance 
  43.      * consequences, so it's not something you want to do always. 
  44.      */  
  45.     String trace = SystemProperties.get("ro.kernel.android.tracing");  
  46.     if (trace.equals("1")) {  
  47.         Slog.i(TAG, "NOTE: emulator trace profiling enabled");  
  48.         Debug.enableEmulatorTraceOutput();  
  49.     }  
  50.   
  51.     initialized = true;  
  52. }  
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.调用进程入口函数

  1. static void invokeStaticMain(ClassLoader loader,  
  2.         String className, String[] argv)  
  3.         throws ZygoteInit.MethodAndArgsCaller {  
  4.     //加载"android.app.ActivityThread"类   
  5.     Class<?> cl;  
  6.     try {  
  7.         cl = loader.loadClass(className);  
  8.     } catch (ClassNotFoundException ex) {  
  9.         throw new RuntimeException("Missing class when invoking static main " + className,  
  10.                 ex);  
  11.     }  
  12.     //通过类反射机制查找ActivityThread类中的main函数   
  13.     Method m;  
  14.     try {  
  15.         m = cl.getMethod("main"new Class[] { String[].class });  
  16.     } catch (NoSuchMethodException ex) {  
  17.         throw new RuntimeException("Missing static main on " + className, ex);  
  18.     } catch (SecurityException ex) {  
  19.         throw new RuntimeException("Problem getting static main on " + className, ex);  
  20.     }  
  21.     //获取main函数的修饰符   
  22.     int modifiers = m.getModifiers();  
  23.     //进程入口函数必须为静态Public类型   
  24.     if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {  
  25.         throw new RuntimeException("Main method is not public and static on " + className);  
  26.     }  
  27.     /* 
  28.      * This throw gets caught in ZygoteInit.main(), which responds 
  29.      * by invoking the exception's run() method. This arrangement 
  30.      * clears up all the stack frames that were required in setting 
  31.      * up the process. 
  32.      */  
  33.     throw new ZygoteInit.MethodAndArgsCaller(m, argv);  
  34. }  
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

  1. public static void main(String argv[]) {  
  2.     try {  
  3.         ...  
  4.     //捕获MethodAndArgsCaller异常   
  5.     } catch (MethodAndArgsCaller caller) {  
  6.         caller.run();  
  7.     } catch (RuntimeException ex) {  
  8.         Log.e(TAG, "Zygote died with exception", ex);  
  9.         closeServerSocket();  
  10.         throw ex;  
  11.     }  
  12. }  
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;
	}
}
在该函数里,捕获了MethodAndArgsCaller异常,并调用MethodAndArgsCaller类的run()方法来处理异常:
  1. public static class MethodAndArgsCaller extends Exception implements Runnable {  
  2.     public void run() {  
  3.         try {  
  4.             mMethod.invoke(nullnew Object[] { mArgs });  
  5.         } catch (IllegalAccessException ex) {  
  6.             throw new RuntimeException(ex);  
  7.         } catch (InvocationTargetException ex) {  
  8.             Throwable cause = ex.getCause();  
  9.             if (cause instanceof RuntimeException) {  
  10.                 throw (RuntimeException) cause;  
  11.             } else if (cause instanceof Error) {  
  12.                 throw (Error) cause;  
  13.             }  
  14.             throw new RuntimeException(ex);  
  15.         }  
  16.     }  
  17. }  
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);
		}
	}
}
这里通过反射机制调用ActivityThread类的main函数,到此新的应用程序进程就创建完毕,同时新的应用程序从ActivityThread.main()函数中开始运行。

frameworks\base\core\java\android\app\ActivityThread.java

  1. public static void main(String[] args) {  
  2.     SamplingProfilerIntegration.start();  
  3.     // CloseGuard defaults to true and can be quite spammy.  We   
  4.     // disable it here, but selectively enable it later (via   
  5.     // StrictMode) on debug builds, but using DropBox, not logs.   
  6.     CloseGuard.setEnabled(false);  
  7.     Process.setArgV0("<pre-initialized>");  
  8.     //为新的应用程序创建消息队列   
  9.     Looper.prepareMainLooper();  
  10.     if (sMainThreadHandler == null) {  
  11.         sMainThreadHandler = new Handler();  
  12.     }  
  13.     //创建一个ActivityThread对象,初始化应用程序运行环境,每一个进程对应一个ActivityThread实例   
  14.     ActivityThread thread = new ActivityThread();  
  15.     //建立与ActivityManagerService之间的Binder通信通道   
  16.     thread.attach(false);  
  17.     AsyncTask.init();  
  18.       
  19.     if (false) {  
  20.         Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));  
  21.     }  
  22.     //为新的应用程序进程启动消息循环,这个消息循环就是应用程序主线程消息循环   
  23.     Looper.loop();  
  24.     throw new RuntimeException("Main thread loop unexpectedly exited");  
  25. }  
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应用进程的启动过程的时序图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值