您的位置:首页 > 移动开发 > Android开发

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

2013-12-11 12:39 513 查看
在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;
}
在该函数里,首先在ActivityManagerService中为即将创建的新应用程序进程创建一个ProcessRecord对象,并保存到mProcessNames进程列表中,然后调用另一个重载函数startProcessLocked来请求创建一个新的应用程序进程。

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);
}
}
在该函数里,首先获取即将创建的应用程序的gid和uid,并设置应用程序进程创建方式,然后调用Process类的start()函数来创建一个新的应用程序进程,同时指定新进程执行的入口为ActivityThread类的main函数。

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);
}
}
该函数直接调用startViaZygote()函数来创建一个新的应用程序进程。

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);
}
}
在该函数里,首先将新的应用程序进程启动参数保存到argsForZygote列表中,然后调用zygoteSendArgsAndGetPid将应用程序进程启动参数发送到Zygote进程。

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);
}
}
该函数首先在SystemServer进程中创建一个客户端LocalSocket,并连接到Zygote进程的名为"zygote"的服务端Socket

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

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

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

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

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

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输出流

/**
* 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;
}
}
在该函数里,捕获了MethodAndArgsCaller异常,并调用MethodAndArgsCaller类的run()方法来处理异常:
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

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应用进程的启动过程的时序图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: