Android应用的启动流程

Zygote通过复制自身的方式来创建一个新的应用程序进程,应用进程在启动的过程中,除了可以获得一个虚拟机实例之外,还可以获得一个Binder线程池和一个消息循环,这样,运行在它里面的应用组件就可以方便地使用Android系统的消息处理机制以及Binder进程间通信机制来实现自己的业务逻辑。

每当AMS(AcitivityManagerService)需要创建一个新的应用程序进程来启动一个应用程序组件时,它就会调用AMS类的成员函数startProcessLocked向Zygote进程发送一个创建应用进程的请求,一共分为八步,俗称天龙八部。

1. StartProcessLocked(AMS)

获取要创建的应用程序进程的用户ID(UID)以及用户组ID (GID),调用Process类的静态成员函数start来创建这个应用程序进程,并且制定这个应用程序进程的入口函数为android.app.ActivityThread类的静态成员函数main。

2. Process.start

调用静态成员函数startViaZygote来请求Zygote进程创建一个应用程序进程。

3. Process.startViaZygote

将要创建的应用程序的启动参数保存在一个字符串列表argsForZygote中,再调用Process类的静态成员函数zygoteSendArgsAndGetPid来请求Zygote进程创建这个应用程序进程。在启动参数列表中,参数“—runtime-int”表示要在新创建的应用程序进程中初始化运行时库以及启动一个Binder线程池

4. Process.zygoteSendArgsAndGetPid

调用静态成员函数openZygoteSocketIfNeeded()来创建一个连接到Zygote进程的LocalSocket对象,将应用程序进程的启动参数列表写入到这个LocalSocket对象,以便可以将他们传递给Zygote进程。Zygote进程接收到这些数据之后,就会创建一个新的应用程序进程,并且将这个新创建的应用程序进程的PID返回给Activity管理服务AMS。

openZygoteSocketIfNeeded

Process类有一个类型为LocalSocket的静态成员变量sZygoteSocket,它是用来与Zygote进程中一个名称为“zygote”的Socket建立连接的。(Zygote进程在启动时,会在内部创建一个名称为“Zygote”的Socket,这个Socket是与设备文件/dev/socket/zygote绑定在一起的)。
创建一个LocalSocket对象,并且保存在Process类的静态成员变量sZygoteSocket里,然后将这个LocalSocket对象与一个名称为ZYGOTE_SOCKET(即zygote的socket地址)建立连接。在连接的过程中,LocalSocket对象sZygoteSocket会在/dev/socket目录下找到一个对性的zygote文件,然后将它与自己帮顶起来,这就相当于与Zygote进程中名为“zygote”的Socket建立了链接。
在连接建立成功后,首先获得LocalSocket对象sZygoteSocket的一个输入流,并且保存在Process类的静态成员变量sZygoteInputStream中,以便获得Zygote进程发送过来的通信数据;接着又获得LocalSocket对象sZygoteSocket的一个输出流,并且保存在Process类的静态成员函数sZygoteWriter中,以便可以向Zygote进程发送通信数据。
Zygote进程在启动完成之后,会在一个名称为“zygote”的socket上等待Activity管理服务AMS向它发送创建新的应用进程的请求。
第5步就是为了和zygote进程进行通信,Zygote进程会在ZygoteInit类的静态成员函数runSelectLoopMode中接收到一个创建新的应用程序进程的请求。

5. ZygoteInit.runSelectLoopMode

当Zygote进程接收到Activity管理服务AMS发送过来的一个创建新的应用进程的请求之后,就会调用ZygoteConnection类的成员函数runOnce来处理这个请求

6. ZygoteConnection.runOnce

首先调用成员函数readArgumentList来获得即将要创建的应用程序的启动参数,把它保存在一个Arguments对象parsedArgs中;再调用Zygote类的静态成员函数forkAndSpecialize来创建这个应用程序进程。
Zygote类的静态成员函数forkAndSpecialize是通过函数fork在当前进程中创建一个子进程的。因此,当它的返回值等于0时,就表示是在新创建的子进程中执行的(父进程Zygote的pid为0),这时ZygoteConnection类就会调用成员函数handleChildProc来启动这个紫禁城。

7. ZygoteConnection.handleChildProc

在第三步中,AMS在创建新的应用程序进程的启动参数列表中设置了一个“——runtime-init”参数,因此这里传进来的Arguments对象parsedArgs的成员变量runtimeInit的值就会等于true。接下来就会调用RuntimeInit类的静态成员函数zygoteInit在新创建的应用进程中初始化运行时库,以及启动一个Binder线程池。

8. RuntimeInit.zygoteInit

zygoteInit首先调用静态成员函数commonInit来设置新创建的应用程序进程的时区和键盘布局等通用信息接着再调用静态成员函数zygoteInitNative在新创建的应用程序进程中启动一个Binder线程池。
回看第一步,我们知道AMS制定了新创建的应用程序进程的入口函数为ActivityThread类的静态成员函数main。因此在zygoteInit中,通过调用RuntimeInit类的静态成员函数invokeStaticMain进入到AcitivityThread类的静态成员函数main中的。

天龙八部终于完了,一个新的应用程序的进程就创建完成,接下来是启动Binder线程池和创建消息循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值