6-系统源码
SurfaceView
SurfaceView 的绘制原理

在 WMS 中会为这个 Window 分配 Surface,并确定显示层级,可见负责显示界面的是画布 Surface,而不是窗口本身,WMS 将他管理的 Surface 交由 SurfaceFlinger 处理,SurfaceFlinger 将这些 Surface 合并后放入到 buffer 中,屏幕会定时从 buffer 中获取显示数据,显示到屏幕上。
SurfaceFlinger
- 在 App 进程中创建 PhoneWindow 后会创建 ViewRoot。ViewRoot 的创建会创建一个 Surface。
- 图像流的最常见消耗方是 SurfaceFlinger,该系统服务会消耗当前可见的 Surface,并使用窗口管理器中提供的信息将它们合成到显示部分。SurfaceFlinger 是可以修改所显示部分内容的唯一服务。SurfaceFlinger 使用 OpenGL 和 Hardware Composer 来合成一组 Surface
- HWComposer 是基于硬件来产生 VSync 信号的,来通知 SurfaceFlinger 重绘控制显示的帧率。
- 图像流生产方可以是生成图形缓冲区以供消耗的任何内容。例如 OpenGL ES、Canvas 2D 和 mediaserver 视频解码器。
![[Pasted image 20250902172407.png]]
刷新率
取的的时间
[[2.Handler 里的各种消息]]
PMS
总结
- 应用安装的时候,通过 PackageManagerService 解析 apk 的 AndroidManifest.xml 文件,提取出这个 apk 的信息写入到 system/packages.xml 文件中,这些信息包括:权限、应用包名、icon、apk 的安装位置、版本、userID 等等。packages.xml 文件位于系统目录下/data/system/packages.xml。
- 同时桌面 Launcher 会为安装过的应用生成不同的应用入口,对应桌面上的应用图标
PackageManagerService
APK安装过程 完全解析
PackageManagerService运行在SystemServer进程,App端和AMS、PMS进行交互都是通过Binder跨进程完成。AMS负责Activity等四大组件的管理,而PMS则负责 包package 的管理,APK的全称是Android Package,即PMS的作用就是管理APK。
1 | |
PMS的初始化
因为 所有App运行都需要 这些系统服务,所以是 系统开机的时候 完成 PMS、AMS这些的初始化
1 | |
在开机系统启动时,zygote 进程会fork一个 SystemServer 进程然后执行上面main方法,这里进行大量的初始化,其中就包括 启动各种服务。 这里我们看 startBootstrapServices():
1 | |
发现这里开启了 AMS、PMS,并且都使用了Installer。Installer 看名字像是安装器,后面再做介绍。 PMS的main方法内用构造方法创建了PMS实例,而它的构造方法内容特别多,我们关注其中一句调用scanDirTracedLI():
1 | |
packages.xml:记录系统中 所有安装的应用信息,包括基本信息、签名和权限。
mSettings:用来保存和PMS相关的一些设置,它保存的内容在解析应用时会用到。
先读取packages.xml文件,解析后将数据存放到mSettings中,代表上次启动时的应用包信息。然后扫描所有APK目录并解析APK,最后更新packages.xml文件。 而 packages.xml文件 是在 Settings 构造方法中创建。
data/app 是用户已安装App所在的目录,另外还有system/app存放 系统App。PMS构造方法中会对 这两个目录在内的多个目录进行扫描,我们这里可以猜想到这是开机时对所有已安装App的初始化。
总结
系统启动后创建并启动了PMS,并且PMS完成了对所有存在APK的目录进行了扫描,解析所有APK的AndroidManifest.xml,然后进一步扫描APK 最后提交包扫描结果到 PMS 的属性中。
APK的安装过程
- APK用写入Session且包信息和APK安装操作 都提交到了PMS;
- PMS中先把APK拷贝到 /data/app,然后使用PackageParser2解析APK 获取 四大组件、搜集签名、PackageSetting等信息,并进行校验确保安装成功;
- 接着提交信息包更新系统状态及PMS的内存数据;
- 然后使用 Installer 准备用户目录/data/user、进行 dexOpt;
- dexOpt 过程:目的:将 APK 中的
.dex字节码转换为优化后的本地机器码 - 最后发送安装结果通知UI层。
crash流程

Context
- Context指:一个应用程序环境的信息,即上下文。Context 是一个接口,ContextImpl 是子类,ContextWapper 是具体实现。

Activity 因为有了 一层 Theme ,所以中间有个 ContextThemeWrapper ,相当于它是Service和Application 的侄子
Context Wrapper 是一个包装类 ,没 任何具体的实现,真正的逻辑都在 Contextlmpl里面
- 可以看出每次创建 Application 和 Acitvity 以及 Service 时就会有一个 ContextImpl 实例,ContentProvider 和B roadcastReceiver 的 Context 是其他地方传入的。
- 所以 Context 数量 = Application 数量 + Activity 数量 + Service 数量,单进程情况下 Application 数量就是 1。
- Application 的 Context 生命周期与应用程序完全相同。Activity 或者 Service 的 Context 与他们各自类生命周期相同。
- Application 通常作为工具类来使用的,Application 中在 onCreate ()方法里去初始化各种全局的变量数据是一种比较推荐的做法,但是如果你想把初始化的时间点提前到极致,也可以去重写 attachBaseContext ()方法。不能写在构造函数里。
注意
虽然 Context 神通广大,但是并不是随便拿到一个 Context 实例就可以为所欲为,还是有一些限制的。在绝大多数场景下,Activity、Service 和 Application 这三种类型的 Context 都是通用的,不过也有几种场景比较特殊,比如启动 Activity、弹出 Dialog。Android 是不允许 Activity 或 Dialog 凭空出现的,一个 Activity 的启动必须建立在另外一个 Activity 的基础之上,也就以此形成任务栈。而 Dialog 则必须在一个 Activity 的上面弹出(除非是 System Alert 类型的 Dialog),因此在这种场景下,我们只能使用 Activity 类的 Context。
- 使用 ApplicationContext 去启动一个 LaunchMode 为 standard 的 Activity。
会报错,因为非 Activity 类型的 Context 没有所谓的任务栈。
- getApplication、getApplicationContext 区别
在绝大多数场景下,getApplication 和 getApplicationContext 这两个方法完全一致,返回值也相同。区别在于 getApplication 只存在于 Activity 和 Service 对象,对于 BroadcastReceiver 和 ContentProvider 只能使用 getApplicationContext。
功能
- 四大组件的交互,包括启动 Activity、Broadcast、Service,获取 ContentResolver 等
- 确定生命周期的、获取各种资源
- 文件、SharedPreference、数据库相关
- 获取系统 / 应用资源,包括 AssetManager、PackageManager、Resources、SystemService 以及 color、string、drawable 等
