《android系统源代码情景分析》学习-第12章Android应用程序进程的启动过程

第1步 AMS.startProcessLocked()

1.1 创建新应用进程的用户ID与用户组ID
1.2 调用Process的静态方法start()创建新进程,指定进程入口是android.app.ActivityThread的main()方法
int pid = Process.start("android.app.ActivityThread",
            "main",uid,uid,gids,debugFlags,null);

第2步 Process.start

检查是否支持进程间通信,startViaZygote()

第3步 Process.startViaZygote

3.1 把要启动的应用进程的启动参数保存在字符串列表argsForZygote中,其中有一个参数”–runtime-init”,代表要在新应用进程中初始化运行时库,以及启动一个Binder线程池
3.2 创建进程
pid = zygoteSendArgsAndGetPid(argsForZygote);

第4步 Process.zygoteSendArgsAndGetPid

4.1 创建一个连接到Zygote进程的LocalSocket对象
openZygoteSocketIdNeeded();
4.1.1 Zygote进程中有一个名为zygote的ServerSocket,对应的设备文件是”/dev/socket/zygote”,负责接受AMS的请求,创建应用进程。

新建一个 LocalSocket实例sZygoteSocket,这个对象与/dev/socket/zygote建立连接,绑定起来,相当于和Zygote进程中的ServerSocket建立了连接。
######4.1.2 LocalSocket与ServerSocket建立连接之后,获取sZygoteSocket的输入流sZygoteInputStream中,用来接受数据;
######4.1.3 获取sZygoteSocket的输出流,用来发送数据

第5步 ZygoteInit.runSelectLoopMode

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

Zygote进程启动后,创建了一个 名为”zygote”的 ServerSocket通过无限循环监听AMS的请求。收到新建应用进程的请求后,会调用runOnce()处理。

第6步 ZygoteConnection.runOnce

6.1 读取请求参数
String args[] = readArgumentList();
Arguments parsedArgs = new Arguments(args);
6.2 创建应用进程
pid = Zygote.forkAddSpecialize(parsedArgs.uid,
        parsedArgs.gid,parsedArgs.gids,
        parsedArgs.debugFlags,rlimits);

forkAndspecialize最终调用了fork()在当前进程创建一个子进程,pid等于0时,代表在新创建的子进程中执行。

6.3 启动子进程
if(pid==0){
//in child
handleChildProc(parsedArgs,descriptions,newStderr);
}

第7步 ZygoteConnection.handleChildProc

在新的应用进程中初始化运行时库,启动一个线程池

if(parsedArgs.runtimeInit){//true
RuntimeInit.zygoteInit(parsedArgs.remainArgs);
}

第8步 RuntimeInit.zygoteInit

8.1 初始化应用进程的时区和键盘布局等信息
commonInit();
8.2 启动Binder线程池
zygoteInitNative();
8.3 进入到ActivityThread

invokeStaticMain(“android.app.ActivityThread”,startArgs);
最终利用反射获取到ActivityThread的静态成员函数main,封装后抛出一个MethodAndArgsCaller异常,这个异常是在ZygoteInit.main中被捕获。
然后执行利用invoke执行main方法。
AMS请求Zygote进程创建的新应用进程的入口就ActivityThread的main方法,但是由于新的应用进程一开始需要先初始化运行时库、启动Binder线程池,所以当ActivityThread的main被调用时实际已经执行了很多代码。为了使得新创建的应用进程觉得它的入口函数就是ActivityThread的main,系统就不直接调用ActivityThread.main, 而是选择抛出一个异常回到ZygoteInit.main,然后再利用反射调用它。

main方法

//创建一个消息循环
Looper.prepareMainLooper();
//创建一个ActivityThread实例 
ActivityThread thread = new ActivityThread();
thread.attach(false);
//进入到消息循环
Looper.loop();

这个ActivityThread就是我们说的主线程,至此,新应用进程的消息循环创建完成,整个进程启动完成。每一个进程在启动完成之后都会自动进入到一个消息循环中,这样应用组件就可以方便第利用消息处理机制实现业务逻辑。

猜你喜欢

转载自blog.csdn.net/u013034413/article/details/79283120