Android 系统启动到App 界面完全展示终于明白(图文版)

前言

系列文章:

Android Activity创建到View的显示过程
Android 四大组件通信核心
Android 系统启动到App 界面完全展示终于明白(图文版)

之前文章有分析过Activity创建到View的显示过程,属于单应用层面的知识范畴,本篇将结合Android 系统启动部分知识将两者串联分析,以期达到融会贯通的目标。
通过本篇文章,你将了解到:

  1. Android 系统启动流程概览
  2. ServiceManager 进程作用
  3. Zygote 进程创建与fork子进程
  4. system_server 进程作用
  5. App 与 system_server 交互
  6. Activity 与 View的展示
  7. 全流程图

1. Android 系统启动流程概览

image.png
  • init 是用户空间的第一个进程,它的父进程是idle进程
  • init 进程通过解析init.rc 文件并fork出相应的进程
  • zygote是第一个Java 虚拟机进程,通过它孵化出system_server 进程
  • system_server 进程启动桌面(Launcher)App

以上为Android 系统上电到桌面启动的简略过程,我们重点关注其中几个进程:

init、servicemanger、zygote、system_server

idle 与 init 关系如下:


image.png

查看依赖关系:


image.png

init.rc 启动servicemanager、zygote 配置如下:


image.png

image.png

2. ServiceManager 进程作用

Android 进程间通信运用最广泛的是Binder机制,而ServiceManager进程与Binder息息相关。
DNS 存储着域名和ip的映射关系,类似的ServiceManager存储着Binder客户端和服务端的映射。


image.png

App1作为Binder Client端,App2 作为Binder Server端,App2 开放一个接口给App1使用(通常称为服务),此时步骤如下:

  1. App2 向ServiceManager注册服务,过程为:App2 获取ServiceManager的Binder引用,通过该Binder引用将App2 的Binder对象(实现了接口)添加到Binder驱动,Binder驱动记录对象与生成handle并返回给ServiceManager,ServiceManager记录关键信息(如服务名,handle)。
  2. App1 向ServcieManager查询服务,过程为: App1 获取ServiceManager的Binder引用,通过该Binder引用发送查询命令给Binder驱动,Binder驱动委托ServiceManager进行查询,ServiceManager根据服务名从自己的缓存链表里查出对应服务,并将该服务的handle写入驱动,进而转为App1的Binder代理。
  3. App1 拿到App2 的Binder代理后,App1 就可以通过Binder与App2进行IPC通信了,此时ServiceManager已经默默退居幕后,深藏功与名。

由上可知,ServiceManager进程扮演着中介的角色。

3. Zygote 进程创建与fork子进程

Zygote 进程的创建

Zygote 进程大名鼎鼎,Android 上所有的Java 进程都由Zygote孵化,Zygote名字本身也即是受精卵,当然文雅点一般称为孵化器。


image.png

Zygote 进程是由init进程fork出来的,进程启动后从入口文件(app_main.cpp)入口函数开始执行:

  1. 构造AppRuntime对象,并创建Java虚拟机、注册一系列的jni函数(Java和Native层关联起来)
  2. 从Native层切换到Java层,执行ZygoteInit.java main()函数
  3. fork system_server进程,预加载进程公共资源(后续fork的子进程可以复用,加快进程执行速度)
  4. 最后开启LocalSocket,并循环监听来自system_server创建子进程的Socket请求。

通过以上步骤,Zygote 启动完成,并等待创建进程的请求。


image.png

初始状态步骤:

  1. Zygote fork system_server 进程并等待Socket请求
  2. system_server 进程启动后会请求打开Launcher(桌面),此时通过Socket发送创建请求给Zygote,Zygote 收到请求后负责fork 出Launcher进程并执行它的入口函数
  3. Launcher 启动后用户就可以看到初始的界面了

用户操作:
桌面显示出来后,此时用户想打开微信,于是点击了桌面上的微信图标,背后的故事如下:

  1. Launcher App 收到点击请求,会执行startActivity,这个命令会通过Binder传递给system_server进程里的AMS(ActivityManagerService)模块
  2. AMS 发现对应的微信进程并没有启动,于是通过Socket发送创建微信进程的请求给Zygote
  3. Zygote 收到Socket请求后,fork 微信进程并执行对应的入口函数,之后就会显示出微信的界面了

用图表示如下:


image.png

由上可知,App进程和system_server 进程之间通信方式为Binder,而system_server和Zygote 通信方式为Socket,App进程并不直接请求Zygote做事情,而是通过system_server进行处理,system_server 记录着当前所有App 进程的状态,由它来统一管理各个App的生命周期。

Zygote 进程fork 子进程

image.png

Zygote 进程在Java层监听Socket请求,收到请求后层层调用最后切换到Native执行系统调用fork()函数,最后根据fork()返回值区分父子进程,并在子进程里执行入口函数。

4. system_server 进程作用

system_server 为所有App提供服务,可以说是系统的核心进程之一,它主要的功能如下:


image.png

可以看出,它创建并启动了许多服务,常见的AMS、PMS、WMS,我们常说系统某某服务返回了啥,往细的说这里的"系统"可以认为是system_server进程。
需要注意的是,这里所说的服务并不是Android四大组件的Service,而是某一类功能。

四大组件的交互也要依靠system_server:


image.png

实际调用流程如下:


image.png

由上图可知,不管是同一进程内的通信亦或是不同进程间的通信,都需要system_server介入。

App 和 system_server 是属于不同的进程,App进程如何找到system_server呢?
还是要借助ServiceManager进程:


image.png

system_server 在启动时候不仅开启了各种服务,同时还将需要暴露的服务注册到ServiceManager里,其它进程想要使用system_server的功能时只需要从SystemManager里查询即可。

5. App 与 system_server 交互

App 想要获取系统的功能,在大部分情况下是绕不过system_server的,接着来看看App如何与system_server进行交互。

前面分析过,App想要获取system_server 服务只需要从ServiceManager里获取即可,调用形式如下:

getSystemService(Context.WINDOW_SERVICE)

那反过来呢?system_server如何主动调用App的服务呢?
既然获取服务的本质是拿到对端的Binder引用,那么也可以反过来,将App的Binder传递给system_server,等到system_server想要调用App时候拿出来用即可,类似回调的功能,如下图:


image.png

再细化一下流程:


image.png
  1. App 进程在启动后执行ActivityThread.java里的main()方法,在该方法里调用system_server的接口,并将自己的Binder引用(mAppThread)传递给system_server
  2. system_server 掌管着Application和四大组件的生命周期,system_server会告诉App进程当前是需要创建Application实例还是调用到Activity某个生命周期阶段(如onCreate/onResume等),此时就是依靠mAppThread回调回来
  3. 此时的App进程作为Binder Server端,它是在子线程收到system_server进程的消息,因此需要通过post到主线程执行
  4. 最终Application/Activity 的生命周期函数将会在主线程执行,这也就是为什么四大组件不能执行耗时任务的原因,因为都会切换到主线程执行四大组件的各种重写方法

6. Activity 与 View的展示

通过上面的分析可知现在的流程已经走到App进程本身,Application、Activity 都已经创建完毕了,什么时候会显示View呢?
先看Activity.onCreate()的调用流程:


image.png

此流程结束,整个ViewTree都构建好了。

接着需要将ViewTree添加到Window里流程如下:


image.png

最后监听屏幕刷新信号,当信号到来之后遍历ViewTree进行Measure、Layout、Draw操作,最终渲染到屏幕上,此时我们的App界面就显示出来了。


image.png

7. 全流程图

image.png

附源码路径:
init.rc配置文件
ServiceManager入口
Zygote native入口
Zygote java入口
system_server入口
App入口

更多Android 源码查看方式请移步:Android-系统源码查看的几种方式

本文基于Android 10
对源码细节有疑惑之处欢迎留言讨论,下篇将会图文分析Binder实现全流程,敬请关注。

您若喜欢,请点赞、关注、收藏,您的鼓励是我前进的动力

持续更新中,和我一起步步为营系统、深入学习Android/Kotlin

1、Android各种Context的前世今生
2、Android DecorView 必知必会
3、Window/WindowManager 不可不知之事
4、View Measure/Layout/Draw 真明白了
5、Android事件分发全套服务
6、Android invalidate/postInvalidate/requestLayout 彻底厘清
7、Android Window 如何确定大小/onMeasure()多次执行原因
8、Android事件驱动Handler-Message-Looper解析
9、Android 键盘一招搞定
10、Android 各种坐标彻底明了
11、Android Activity/Window/View 的background
12、Android Activity创建到View的显示过
13、Android IPC 系列
14、Android 存储系列
15、Java 并发系列不再疑惑
16、Java 线程池系列
17、Android Jetpack 前置基础系列
18、Android Jetpack 易懂易学系列
19、Kotlin 轻松入门系列
20、Kotlin 协程系列全面解读

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容