2023年11月26日发(作者:)
⼀个APP从启动到主页⾯显⽰经历了哪些过程?(App启动流程,从点击桌⾯开
始)
本⽂以图⽂并茂的形式简单介绍⼀个APP从启动到主页⾯显⽰经历了哪些流程,以及实现的原理。不介绍具体源码,仅仅构建⼀个⼤体框架。
⼀、流程概述
启动流程:
①点击桌⾯App图标,Launcher进程采⽤Binder IPC向system_server进程发起startActivity请求;
②system_server进程接收到请求后,向zygote进程发送创建进程的请求;
③Zygote进程fork出新的⼦进程,即App进程;
④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
⑤system_server进程在收到请求后,进⾏⼀系列准备⼯作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
下⾯我们⼀⼀介绍。
⼆、理论基础
zygote意为“受精卵“。Android是基于Linux系统的,⽽在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zygote进
程也不例外。
在Android系统⾥⾯,zygote是⼀个进程的名字。Android是基于Linux System的,当你的⼿机开机的时候,Linux的内核加载完成之后
就会启动⼀个叫“init“的进程。在Linux System⾥⾯,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。
我们都知道,每⼀个App其实都是
● ⼀个单独的dalvik虚拟机
● ⼀个单独的进程
所以当系统⾥⾯的第⼀个zygote进程运⾏之后,在这之后再开启App,就相当于开启⼀个新的进程。⽽为了实现资源共⽤和更快的启动速
度,Android系统开启新进程的⽅式,是通过fork第⼀个zygote进程实现的。所以说,除了第⼀个zygote进程,其他应⽤所在的进程都是
zygote的⼦进程,这下你明⽩为什么这个进程叫“受精卵”了吧?因为就像是⼀个受精卵⼀样,它能快速的分裂,并且产⽣遗传物质⼀样的
细胞!
在Android系统中,任何⼀个Activity的启动都是由AMS和应⽤程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统⼀调
度系统中所有进程的Activity启动,⽽每个Activity的启动过程则由其所属的进程具体来完成。
er
当我们点击⼿机桌⾯上的图标的时候,App就由Launcher开始启动了。但是,你有没有思考过Launcher到底是⼀个什么东西?
Launcher本质上也是⼀个应⽤程序,和我们的App⼀样,也是继承⾃Activity
packages/apps/Launcher2/src/com/android/launcher2/
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
View.OnTouchListener {
}
Launcher实现了点击、长按等回调接⼝,来接收⽤户的输⼊。既然是普通的App,那么我们的开发经验在这⾥就仍然适⽤,⽐如,我们点
击图标的时候,是怎么开启的应⽤呢?捕捉图标点击事件,然后startActivity()发送对应的Intent请求呗!是的,Launcher也是这么做的,
就是这么easy!
mentation和ActivityThread
每个Activity都持有Instrumentation对象的⼀个引⽤,但是整个进程只会存在⼀个Instrumentation对象。
Instrumentation这个类⾥⾯的⽅法⼤多数和Application和Activity有关,这个类就是完成对Application和Activity初始化和⽣命周期的⼯
具类。Instrumentation这个类很重要,对Activity⽣命周期⽅法的调⽤根本就离不开他,他可以说是⼀个⼤管家。
ActivityThread,依赖于UI线程。App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交⼯作的。
ationThread
前⾯我们已经知道了App的启动以及Activity的显⽰都需要AMS的控制,那么我们便需要和服务端的沟通,⽽这个沟通是双向的。
客户端–>服务端
⽽且由于继承了同样的公共接⼝类,ActivityManagerProxy提供了与ActivityManagerService⼀样的函数原型,使⽤户感觉不出Server
是运⾏在本地还是远端,从⽽可以更加⽅便的调⽤这些重要的系统服务。
服务端–>客户端
还是通过Binder通信,不过是换了另外⼀对,换成了ApplicationThread和ApplicationThreadProxy。
他们也都实现了相同的接⼝IApplicationThread
private class ApplicationThread extends ApplicationThreadNative {}
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{}
class ApplicationThreadProxy implements IApplicationThread {}
关于Binder通信,可以参考这两篇⽂章理解⼀下:
好了,前⾯罗⾥吧嗦的⼀⼤堆,介绍了⼀堆名词,可能不太清楚,没关系,下⾯结合流程图介绍。
三、启动流程
1.创建进程
①先从Launcher的startActivity()⽅法,通过Binder通信,调⽤ActivityManagerService的startActivity⽅法。
②⼀系列折腾,最后调⽤startProcessLocked()⽅法来创建新的进程。
③该⽅法会通过前⾯讲到的socket通道传递参数给Zygote进程。Zygote孵化⾃⾝。调⽤()⽅法来实例化ActivityThread
对象并最终返回新进程的pid。
④调⽤()⽅法,ActivityThread随后依次调⽤eLoop()和()来开启消息循环。
⽅法调⽤流程图如下:
更直⽩的流程解释:
①App发起进程:当从桌⾯启动应⽤,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进
程。发起进程先通过binder发送消息给system_server进程;
②system_server进程:调⽤()⽅法,通过socket向zygote进程发送创建新进程的请求;
更直⽩的流程解释:
(如果看不懂AMS,ATP等名词,后⾯有解释)
3.显⽰Activity界⾯
经过前两个步骤之后, 系统已经拥有了该application的进程。 后⾯的调⽤顺序就是普通的从⼀个已经存在的进程中启动⼀个新进程的
更直⽩的流程解释:
四、Binder通信
简称:
发布评论