首先回顾下冷启动的流程图:
共有四个步骤:
1.launcher进程通过binder请求ams启动Activity,AMS进程查询内存中是否存在该进程。
2.内存中无相应进程,ams通过socket发送创建进程命令和相关资料到zygote进程。
3.zygote进程收到socket信息后,fork子进程,创建出ActivityThread的进程(目的进程)
4.ActivityThread通过binder把新建的进程信息与AMS进行相关联。
在上一篇博客中探索APP进程的启动流程(一),介绍了从用户点开app到发送指令给zygote进程的过程(步骤1,步骤2)。
再往下就去到Zygote进程(步骤3,步骤4),Zygote接收到初始化进程指令,fork子进程。
(剧透:如果没时间看源码,可以直接去到本文末尾,有 zygote进程等待socket消息和处理的简单模型 图)
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
//ZygoteServer处理有关socket服务端的业务
ZygoteServer zygoteServer = new ZygoteServer();
...
///注册Zygote的Socket服务端
zygoteServer.registerServerSocketFromEnv(socketName);
...
if (startSystemServer) {
//开启SystemServer
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
//等待客户端请求,
//在runSelectLoop()里面是while(true),线程堵塞等到客户端的socket发送信息
zygoteServer.runSelectLoop(abiList);
//关闭Socket服务端
zygoteServer.closeServerSocket();
...
}
zygoteServer. runSelectLoop(), 进行接收socket客户端信息
\frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
Runnable runSelectLoop(String abiList) {
...
ZygoteConnection connection = peers.get(i);
//接收到socket客户端信息,processOneCommand进行处理
final Runnable command = connection.processOneCommand(this);
...
}
\frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
继续看看processOneCommand()如何处理socket信息
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
//readArgumentList函数来获取启动应用程序进程的命令参数
args = readArgumentList();
...
//将readArgumentList函数返回的字符串args封装到Arguments对象parsedArgs中
parsedArgs = new Arguments(args);
...
//调用Zygote的forkAndSpecialize函数来创建应用程序进程,
//参数为parsedArgs中存储的应用进程启动参数,返回值为pid
//forkAndSpecialize函数主要是通过fork当前进程来创建一个子进程(native完成)
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
...
if (pid == 0) {
// 如果pid等于0,则说明是现在在新创建的子进程中执行
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
,
//调用 handleChildProc 函数来启动这个子进程也就是应用程序进程
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
}
...
}
\frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java
进去handleChildProc()看看
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
//zygoteInit() 来初始化进程
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
...
}
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
...
// 新创建的应用程序进程中创建Binder线程池
ZygoteInit.nativeZygoteInit();
//初始化进程入口类ActivityThread
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
// args.startClass 为 从AMS的startProcessLocked()传入的参数
return findStaticMain(args.startClass, args.startArgs, classLoader);
...
}
再跟进findStaticMain():
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
...
//根据类加载器,获得Android.app.ActivityThread类
cl = Class.forName(className, true, classLoader);
...
Method m;
...
//获得ActivityThread.java main()
m = cl.getMethod("main", new Class[] { String[].class });
...
//把调用ActivityThread. main()的runnable实例返回
return new MethodAndArgsCaller(m, argv);
}
new MethodAndArgsCaller(m, argv)返回的runnable实例到ZygoteInit类的caller对象。 在ZygoteInit.main()方法中执行caller.run()
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
...
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
//子进程会离开socket服务端等待信息的循环
if (caller != null) {
caller.run();
}
MethodAndArgsCaller.run()执行了,ActivityThread.main()。
在代码,有:
static class MethodAndArgsCaller implements Runnable {
....
public void run() {
try {
//mMethod为ActivityThread.main()方法。这里调用ActivityThread的main()
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类(进程的入口类)
\frameworks\base\core\java\android\app\ActivityThread.java
//ApplicationThread 为 ActivityThread内部类,是binder服务的服务端
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
...
//初始化进程的主线程 Looper
Looper.prepareMainLooper();
...
//实例化 ActivityThread 对象
ActivityThread thread = new ActivityThread();
//在attach()方法里进行请求ams绑定当前新建的进程
thread.attach(false, startSeq);
...
//loop启动
Looper.loop();
...
}
继续跟进attach()
\frameworks\base\core\java\android\app\ActivityThread.java
private void attach(boolean system, long startSeq) {
...
//获得ActivityManagerService服务
final IActivityManager mgr = ActivityManager.getService();
//调用ActivityManagerService.attachApplication(),并传入mAppThread。请求关联进程
mgr.attachApplication(mAppThread, startSeq);
...
}
zygote进程等待socket消息和处理的简单模型
将上述的代码分析,转成流程图形式:
< zygote进程等待socket消息和处理的简单模型>
在这两篇文章里,只对进程的创建做分析。对于APP的启动流程,这里先不做细节分析,后续文章再继续简述APP的启动流程。
来到这里,从 新建一个进程 到 把进程与AMS关联的关键步骤已大概分析介绍。如果有其他疑问或有错误地方可以给我留言哦。