首先回顾下冷启动的流程图: 共有四个步骤: 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消息和处理的简单模型>
在这两篇文章里,只对进程的创建做分析。对于APP的启动流程,这里先不做细节分析,后续文章再继续简述APP的启动流程。
来到这里,从 新建一个进程 到 把进程与AMS关联的关键步骤已大概分析介绍。如果有其他疑问或有错误地方可以给我留言哦。