《Android 系统源代码情景分析》,博客 AOSP Version:2.3
- 每当AMS需要创建新的APP进程来启动Activity这些组件时,它会调用
ActivityManagerService.
中的startProcessLocked()
向Zygote
发送一个创建APP进程的请求.
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
private final void startProcessLocked(ProcessRecord app,String hostingType, String hostingNameStr) {
...
try {
//获取APP进程的用户id
int uid = app.info.uid;
int[] gids = null;
try {
//获取APP进程的用户组id
gids = mContext.getPackageManager().getPackageGids(app.info.packageName);
} catch (PackageManager.NameNotFoundException e) {
Slog.w(TAG, "Unable to retrieve gids", e);
}
...
// 创建APP进程
// "android.app.ActivityThread":指定应用程序入口函数在ActivityThread类中
int pid = Process.start("android.app.ActivityThread",
mSimpleProcessManagement ? app.processName : null, uid, uid,
gids, debugFlags, null);
...
// Zygote创建的APP进程的pid被保存到该进程对应的ProcessRecord对象的pid变量中
app.pid = pid;
...
}
}
}
- 发送Socket消息给Zygote
public class Process {
public static final int start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags,
String[] zygoteArgs)
{
// supportsProcesses():判断系统是否支持Binder通信
if (supportsProcesses()) {
try {
// 请求Zygote创建APP进程
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
...
}
} ...
}
private static int startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags,
String[] extraArgs)
throws ZygoteStartFailedEx {
int pid;
synchronized(Process.class) {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-init 它表示要在新的进程中初始化运行时库以及启动一个Binder线程池
argsForZygote.add("--runtime-init");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
...
// 发送请求信息
pid = zygoteSendArgsAndGetPid(argsForZygote);
}
...
return pid;
}
private static int zygoteSendArgsAndGetPid(ArrayList<String> args) throws ZygoteStartFailedEx {
int pid;
// 先看下这个方法
// 建立Socket客户端,并且让客户端与Zygote进程中的Socket服务端进行链接.
// 链接成功了就可以向Socket服务端发送创建APP进程信息.
openZygoteSocketIfNeeded();
try {
// 这里就开始向Zygote发送信息了
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();
// 获取新创建APP进程的pid,这个pid最终会存入ProcessRecord中的pid变量中.
pid = sZygoteInputStream.readInt();
...
} catch (IOException ex) {
...
}
return pid;
}
private static final String ZYGOTE_SOCKET = "zygote";
// 创建Socket客户端对象
private static void openZygoteSocketIfNeeded() throws ZygoteStartFailedEx {
int retryCount;
for (int retry = 0 ; (sZygoteSocket == null) && (retry < (retryCount + 1)) ; retry++ ) {
...
try {
sZygoteSocket = new LocalSocket();
// sZygoteSocket对象与名称为"zygote"的地址建立链接,也就是在这里与Zygote进程中的Socket服务端建立了链接
sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,LocalSocketAddress.Namespace.RESERVED));
// 获取Socket客户端的输入流
sZygoteInputStream = new DataInputStream(sZygoteSocket.getInputStream());
// 获取Socket客户端的输出流
sZygoteWriter = new BufferedWriter( new OutputStreamWriter(sZygoteSocket.getOutputStream()),256);
break;
} catch (IOException ex) {
...
}
}
}
}
- Zygote接收到消息
public class ZygoteInit {
public static void main(String argv[]) {
try {
// 这里就是注册Socket服务端
registerZygoteSocket();
...
// 启动SystemServer进程
startSystemServer();
// 监听Socket服务端
runSelectLoopMode();
closeServerSocket();
}
}
private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
// 注册Socket服务端
private static void registerZygoteSocket() {
if (sServerSocket == null) {
int fileDesc;
try {
// 得到Socket的环境变量
String env = System.getenv(ANDROID_SOCKET_ENV);
// 将Socket环境变量值转换为文件描述符参数
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
...
}
try {
// 创建服务器端Socket
sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));
} catch (IOException ex) {
...
}
}
}
// 对sServerSocket监听
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);
while (true) {
...
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
// 这里是链接成功的处理逻辑
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
// 收到创建APP进程消息处理逻辑
boolean done;
// 开始创建进程
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
}
- 开始fork子进程
class ZygoteConnection {
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
...
int pid;
try {
..
// forkAndSpecialize()理解
// 该方法是调用一次,返回两次.它会在Zygote进程中调用一次,在Zygote进程和子进程中各返回一次.
// 通过返回的进程pid判断当前是走到了Zygote进程中还是APP子进程中.
// 如果是APP子进程中,最终将会在该进程中调用熟悉的ActivityThread.java中的main().
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids, parsedArgs.debugFlags, rlimits);
}
if (pid == 0) {
// 处理APP进程
handleChildProc(parsedArgs, descriptors, newStderr);
return true;
} else {
return handleParentProc(pid, descriptors, parsedArgs);
}
}
// 处理APP进程
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller {
// 在AMS中,启动一个APP进程时候在Process.startViaZygote()设置了argsForZygote.add("--runtime-init"); ,
// 表示要初始化一个运行时库以及启动一个Binder线程池
if (parsedArgs.runtimeInit) {
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
}
}
}
- 对fork出的APP进程进行处理
public class RuntimeInit {
public static final void zygoteInit(String[] argv) throws ZygoteInit.MethodAndArgsCaller {
...
// 设置时区和键盘布局信息
commonInit();
// 启动Binder线程池
zygoteInitNative();
...
// 开始调用ActivityThread.java中的main();
invokeStaticMain(startClass, startArgs);
}
private static void invokeStaticMain(String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
...
Class<?> cl;
try {
cl = Class.forName(className);
} catch (ClassNotFoundException ex) {
...
}
Method m;
try {
// 获取main()
m = cl.getMethod("main", new Class[] { String[].class });
}
...
// 这里看起来很奇怪, 其实很好理解
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
}
- 清除调用过程的堆栈信息
- 最初接收Socket客户端消息并处理是在
ZygoteInit.main()
,如果RuntimeInit.invokeStaticMain()
抛出异常,最终会抛到ZygoteInit.main()
中.
public class ZygoteInit {
public static void main(String argv[]) {
try {
...
} catch (MethodAndArgsCaller caller) {
// MethodAndArgsCaller caller: 将RuntimeInit.invokeStaticMain()中抛出的异常捕获到了
// 看看它的run()
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
public static class MethodAndArgsCaller extends Exception implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// 这里最终将调用ActivityThread.java中的main().
mMethod.invoke(null, new Object[] { mArgs });
}
...
}
}
}
- App进程中UI线程进入消息循环
- 当APP进程启动之后,就会调用ActivityThread.main(),在这里将会启动UI线程得消息循环.
// ActivityThread.java
public final class ActivityThread {
public static final void main(String[] args) {
...
// 创建looper对象,设置主线程looper.
Looper.prepareMainLooper();
...
// 为该线程得looper开启消息循环监听,这样主线程的Handler机制就开动起来了.
Looper.loop();
...
}
}
//Looper.java
public class Looper {
public static final void prepareMainLooper() {
prepare();// 为当前线程准备新的looper对象,并与当前线程关联.
setMainLooper(myLooper());// 获取当前线程对应的looper对象,将该looper对象设置为mMainLooper变量值.
...
}
}