为什么要学 Framework?
Posted 初一十五啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么要学 Framework?相关的知识,希望对你有一定的参考价值。
为什么要学 Framework?
最直接最功利的原因就是面试要问,比如:
- Activity 的启动过程,这个会涉及到 AMS/ATMS 和 WMS 的实现
- Binder 如何通过一次拷贝完成 IPC
- View 的绘制流程
- SurfaceFlinger 的工作原理与流程
- …
对于应用开发来说,大部分类似的题目是没有太大意义的。在2023年,面试的内容已经在 app 层挖掘完了,再想提高面试门槛就只能往深了挖。Framework 的内容足够多,应聘者不可能熟悉所有的源码,只要面试官愿意,肯定能问倒应聘者的。
如果我们能系统科学地学习 Framework,掌握 Framework 中基础的核心的内容,以不变应万变。当问到我们不熟悉的部分,大胆承认,说出该部分内容会涉及到哪些基础内容,如何着手去分析,面试官大概率也会给过的。
android 的应用非常广泛,不仅是手机,可能汽车,手表,冰箱,微波炉,电视,机顶盒,空调的内部都有一个 Android 系统。广泛的应用促使了对 Framework 人才的大量需求,因为 Framework 学习门槛较高,导致企业招聘相对困难,薪资也比大部分 App 开发岗位高出不少。如果能系统地学习 Framework 并加入这类企业,不论从经济上还是个人职业发展上都是非常不错的选择。
什么是 Android Framework
什么是 Android Framework? 我们先看一下 Android 的整体结构图
从下往上依次是:
- Linux kernel 层,很大一部分内容是驱动程序
- HAL 层,对下封装驱动硬件操作,对上向 App 提供统一稳定的驱动操作接口
- Native层,主要是 C/C++ 库以及 Java 虚拟机
- Java 层,主要是 Java 库,系统服务等
- App 层,一些系统和三方APP
我们常说的 framework 大多数指的是中间三层的开发,即 Java层、Native层、HAL层
以 Android 系统启动过程为主线,以进程的视角来学习 Android 系统全貌,更为清晰明了:
Android 系统启动过程由上图从下往上的一个过程是由 Boot Loader 引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App
- kernel 层主要向上提供了驱动,Hal 层加以封装后,向上提供驱动程序功能
- Native 层通过 init 进程启动了很多守护进程用于支持系统的运转
- Java 层通过 Zygote 孵化了 Java 守护进程,用于支持系统的运行和 App 的运行
Framework 开发做什么
谷歌几乎每年都会发布最新的 AOSP 原生代码,AOSP 原生代码只支持极少数几款手机,比如 Pixel。
芯片厂商根据自己的芯片的特点修改 AOSP ,让其可以在自己芯片上跑起来
方案厂商根据自己开发的设备特点(主要是外设 如wifi 蓝牙 传感器等),修改芯片厂提供的源码,使得软件能在方案厂商的开发板上跑起来
大部分做产品的厂商拿到的就是芯片厂商提供的开发板硬件和系统源码,产品厂商主要工作就是:
- 添加自己的硬件、驱动、HAL和硬件系统服务,硬件的提供商可能会提供相应软件支持
- 定制系统 App,比如 Launcher Setting System UI Message Camera 等
- 开发厂商自己的系统 App,比如 音视频播放器 应用商店 主题 红外遥控等
- 个性化功能开发,比如软件多开,手机分身,语音变声,录屏,双卡双待等等
- 集成一些常用三方应用,比如 微信 淘宝 爱奇艺等
- 系统稳定性 性能 安全相关优化
- 系统裁剪
方案厂商提供的系统源码并不完美,App 中很多的 Bug 可能是 Framework 层导致的,产品在上市前需要针对系统 App 和热门三方 App 及游戏进行测试,解决掉 Framework 中存在的 bug。Framework 开发的主要工作就是解决这些 bug 并协助系统 App 的开发,同时可能要做一些新特性开发,系统性能和安全相关的工作。
Framework 中无穷无尽的 bug 也不能怪芯片厂商和方案厂商,因为 Android 打娘胎里出来就有数不清的 bug,在这里可以查看 aosp 相关的 bug 信息。
Framework 学什么
从 Framework 的工作内容和特点来看,我们应该花主要的精力学习基础和核心模块,然后在工作中学习涉及到的具体的模块。
系统源码非常的庞大与复杂,在学习过程中一定要有分层与黑盒的思想!
我总结了 11 个专题,逐个击破 Framework 基础核心内容:
1. 基础知识
编程语言方面我们需要掌握:
- C/C++
- Java
- JNI
其次我们对一些工具类的语言有一定的了解:
- Python:源码下载工具 repo 使用 python 对 git 操作做了封装,以适应多个 git 仓库的操作
- Shell 编程:Android 编译系统包含了大量的 Shell 脚本
- go 语言,Android 编译系统中部分脚本使用 go 语言编写
早期 Android 编译系统使用 make 构建,后来逐步使用 Soong 进行替换,Android 的官方博客指出未来会使用 Bazel 来替换掉目前 make 和 Soong 混合的结构,鉴于 Android 代码量庞大,这些替换都是部分的逐步开展的,所以三者都得有所了解
对于 Linux 需要掌握三个方面:
- 熟悉 Linux 的基本使用,主要是常用的命令和常用服务搭建
- 熟悉 Linux 系统编程,Native 层使用了很多系统编程接口,熟悉 Linux 系统编程是读懂 Native 层的基础
- Linux 系统编程可能或多或少需要我们对 Linux 内核有基本的了解
另外在 Linux 的学习工程中兼顾一下操作系统基础的学习
2. AOSP 源码上手
有了基础知识以后,我们就可以上手玩一玩 AOSP 源码了:
这里主要是一些实际操作,编译好 AOSP,并添加一些功能。同时了解一下系统源码的管理,掌握 repo 和 gerrit 的使用。
3. AOSP 编译系统
在上手了 AOSP 源码后,我们需要知道,我们的系统是怎么编译的,怎么烧录到手机上的。
4. Hal与硬件服务
这里需要我们自己动手:
- 完成一个简单字符驱动程序的编写
- 完成 Hal 层编写,首先掌握传统方式,再学习基于 HwBinder 的现代方式
- 最后就是在系统中添加硬件服务,写个简单的 App 访问我们的硬件服务
以上内容使我们从整体上了解了外设软件开发流程。
5. 基础组件
基础组件就是被使用的比较多的组件,主要包含了:
- Android 智能指针
- Android 属性系统
- Android 日志系统
- SeAndroid
- Android 权限系统
- 匿名共享内存
6. Binder
Binder 是 Android 最核心的基础,整个 Android 都是基于 Binder 搭建的,不夸张的讲,不懂 Binder 就不懂 Android。
Binder 涉及了内核驱动层,C 层,C++ 层,Java 层,涉及知识多,流程复杂,很多人学了一遍有一遍,还是没有掌握。
这一次,我们从三个四的角度彻底搞懂 Binder !
7. 系统启动过程分析
主要熟悉整个系统启动的流程:
重点掌握:
- init 的实现细节
- Zygote 的具体实现
- SystemServer 的内部实现
8. 应用层框架
主要搞懂:
- AMS/ATMS
- Handler 和 Looper
- PackageManagerService
9. 显示系统
在掌握了 Android 显示系统整体框架后,再逐步学习一下内容:
- Hal 层的 Gralloc 和 Hwcomposer
- Surfaceflinger
- WMS
- View 系统
10. Android 输入系统
输入系统主要三个方面来具体学习:
- 读取事件
- 分发事件
- 处理事件
11. 系统应用
对系统应用的开发要有所了解,主要学习一下几个 App:
- Calculator
- Setting
- Launcher
- SystemUI
总结
在掌握了这 11 个专题后,不论是继续研究 Framework 中其他模块,或是参与 App 开发,又或是研究内核与驱动,我相信,你一定早已是是游刃有余了!
Framework 参考学习笔记推荐:https://qr18.cn/AQpN4J
《Android Framework学习手册》:
- 开机Init 进程
- 开机启动 Zygote 进程
- 开机启动 SystemServer 进程
- Binder 驱动
- AMS 的启动过程
- PMS 的启动过程
- Launcher 的启动过程
- Android 四大组件
- Android 系统服务 - Input 事件的分发过程
- Android 底层渲染 - 屏幕刷新机制源码分析
- Android 源码分析实战
以上是关于为什么要学 Framework?的主要内容,如果未能解决你的问题,请参考以下文章
Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动
Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动