在前面的介绍的Activity启动流程中,跳过了进程的构建和ActivityThread开始运行的部分,本文就详细展开该过程。
ActivityManagerService启动一个新的进程作为容器
ActivityManagerService.java
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) {
// Process里面通知Zygote服务,Zygote真正产生新的进程(准确说是复制一个)
int pid = Process.start("android.app.ActivityThread",
mSimpleProcessManagement ? app.processName : null, uid, uid,
}
Process.java
public static final int start(final String processClass, final String niceName,
int uid, int gid, int[] gids, int debugFlags, String[] zygoteArgs)
{
// 现在的android系统都是支持多进程的,所以应用程序都在单独的进程控件中运行
if (supportsProcesses()) {
// 由Zygote服务启动新的进程
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, zygoteArgs);
} else {
// 单进程模式,所有的Android 应用都共享同一个进程 空间
Runnable runnable = new Runnable() {
public void run() {
Process.invokeStaticMain(processClass);
}
};
// Thread constructors must not be called with null names (see spec).
if (niceName != null) {
new Thread(runnable, niceName).start();
} else {
new Thread(runnable).start();
}
return 0;
}
}
private static int startViaZygote(final String processClass, final String niceName,
final int uid, final int gid, final int[] gids, int debugFlags, String[] extraArgs)
{
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-init
argsForZygote.add("--runtime-init");
// 设置进程的uid和gid
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
// --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);
// 通过socket将参数列表传给Zygote并返回新生的进程ID
pid = zygoteSendArgsAndGetPid(argsForZygote);
}
}
Zygote服务监听本地/dev/socket设备
private static void runSelectLoopMode() throws MethodAndArgsCaller {
while (true) {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
//
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
boolean runOnce() {
// fork调用,复制zygote进程产生子进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, parsedArgs.debugFlags, rlimits);
if (pid == 0) {
// in child
handleChildProc(parsedArgs, descriptors, newStderr);
// should never happen
return true;
} else {
return handleParentProc(pid, descriptors, parsedArgs);
}
}
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, PrintStream newStderr){
// 前面Process::startViaZygote时,传入参数"--runtime-init",所以这里为true(估计是代表需要用的类已经被装入过了)
if (parsedArgs.runtimeInit) {
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
} else {
ClassLoader cloader;
if (parsedArgs.classpath != null) {
cloader
= new PathClassLoader(parsedArgs.classpath,
ClassLoader.getSystemClassLoader());
} else {
cloader = ClassLoader.getSystemClassLoader();
}
String className;
className = parsedArgs.remainingArgs[0];
String[] mainArgs
= new String[parsedArgs.remainingArgs.length - 1];
System.arraycopy(parsedArgs.remainingArgs, 1,
mainArgs, 0, mainArgs.length);
ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
}
}
RuntimeInit.java
public static final void zygoteInit(String[] argv) throws ZygoteInit.MethodAndArgsCaller {
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
commonInit();
zygoteInitNative();
int curArg = 0;
for ( /* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
Process.setArgV0(niceName);
}
}
if (curArg == argv.length) {
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
private static void invokeStaticMain(String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
Class<?> cl;
cl = Class.forName(className);
Method m;
m = cl.getMethod("main", new Class[] { String[].class });
/*
* 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);
}
这之后就是ActivityThread::main被执行,产生ActivityThread对象并注册给ActivityManagerService。
IActivityManager是ActivityThread调用ActivityManagerServcie的功能接口
ActivityThread--->IActivityManager--->ActivityManagerServcie
ApplicationThread则是ActivityManagerServcie调用ActivityThread的功能接口
ActivityThread<--ApplicationThread<--ActivityManagerServcie