安卓(Android)是一种基于 Linux 内核(不包含 GNU 组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由美国 Google 公司和 开放手机联盟 领导及开发。Android 操作系统最初由 Andy Rubin 开发,主要支持手机。2005年8月由 Google 收购注资。2007年11月,Google 与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良 Android 系统。随后 Google 以 Apache 开源许可证的授权方式,发布了 Android 的源代码。第一部 Android 智能手机发布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视、数码相机、游戏机、智能手表等。
Android 的架构
-
系统演进
- 从 Android 1.0 发展到 Android 4.0,系统各项功能和特性迭代到一个较完善的阶段;
- Android 4.1 系统,Google 开展了黄油计划(Project Butter),为了让 Android 系统摆脱 UI 交互上的严重滞后感,希望能像“黄油”一样顺滑。 核心原理是系统框架中的渲染和动画统一采用垂直同步技术(VSYNC),以及三重缓冲技术(Triple Buffer),让滑动、翻页等操作更加一致与顺滑。
对于 VSYNC 信号和 Triple Buffering 更详细的介绍,可以参考《Android Project Butter 分析》。
- Android 4.4 系统,Google 开展了瘦身计划(Project Svelte),力求降低安卓系统的内存使用,解决低端机型升级难的问题,让 Android 4.4 可正常运行在所有 Android 手机,从而减少安卓系统继续碎片化。UI 设计上,支持新的“沉浸式模式”,用户界面由过去的黑色与蓝色为主的色调转向带有透明度的浅色系,视觉语言变得更加明亮与现代化。
Android 4.4 应该是里程式的改进。
- Android 5.0 系统,Google 开展了伏特计划(Project Volta),力求提升续航能力,这方面 Google 落后于业界厂商,厂商直面用户对续航尤为迫切,往往系统资源管控更为严格。另外,系统采用全新的 ART,抛弃 Dalvik 虚拟机,大幅提升运行效率。UI 设计上,使用全新的扁平化 Material Design 设计风格,更加清新与质感的设计,统一 Android 设备的外观和使用体验。
对于 ART 和 Dalvik 虚拟机的区别,可以参考《Android Runtime (ART) 和 Dalvik》
- Android 6.0 系统,Google 引入新的运行时权限,让用户能够更好地了解和控制权限;引入了 Doze 模式,进一步提升电池续航能力。UI 设计上,新增夜间模式,大幅改进通知栏,让通知更简洁。
运行时权限的管理参考此文章《Android运行时权限终极方案,用PermissionX吧》
- Android 7.0 系统,引入新的 JIT 编译器,对 AOT 编译器的补充,可节省存储空间和加快更新速度;进一步优化 Doze 唤醒机制;UI 设计上,支持分屏功能;
了解 JIT 编译器参考此文章《JIT编译器》
- Android 8.0 系统,Google 开展了重构计划( Project Treble),重新架构 Android,将安卓系统框架与 Vendor 层解耦,力求彻底解决安卓碎片化这一老大难的问题,这是安卓系统架构最大的变化。系统层面加强对后台服务、广播、位置的管控限制。UI 设计上,改进通知栏,智能文本选择和自动填充功能。
对 Android 8.0 的系统更多了解参见文章《Android Project Treble机制解析》
- Android 9.0 系统,引入神经网络 API,采用机器学习的思路来预测用户使用习惯来做省电优化,继续强化 Treble 计划;文件系统(sdcardf/F2FS)持续提升;私有 API 的限制进一步规范化 Android 生态,强化隐私和安全,硬件安全性模块以及统一生物识别身份验证界面。 UI 设计上,新的手势导航,加强支持刘海屏,UI 搜索界面使用到机器学习,AI 正在逐步强化 Android 系统。
- Android 10.0 系统,Google 开展了主线计划(Project Mainline),相关模块(Modules)不允许厂商直接修改,只能由 Google 应用商店来更新升级,强化用户隐私、系统安全与兼容性。支持脸部生物识别。
但是中国用户例外
- Android 11.0 系统,采用了文件沙盒存储模式,导致第三方应用无法像以前一样访问 Android/data目录,通过这些变更和限制来加强用户隐私保护;添加了 5G API.
- Android 12.0 系统,使用 Material You 打造的全新系统界面,增强 AppSearch、游戏模式和新的编解码器;支持隐私信息中心和大致位置等新的保护功能;
Android技术架构演进与未来、android开发者文档
-
整体架构
-
应用程序
Android 随附一套用于电子邮件、短信、日历、互联网浏览和联系人等的核心应用。平台随附的应用与用户可以选择安装的应用一样,没有特殊状态。因此第三方应用可成为用户的默认网络浏览器、短信 Messenger 甚至默认键盘(有一些例外,例如系统的“设置”应用)。
系统应用可用作用户的应用,以及提供开发者可从其自己的应用访问的主要功能。例如,如果您的应用要发短信,您无需自己构建该功能,可以改为调用已安装的短信应用向您指定的接收者发送消息。
国内各大厂商在修改 Framewort 时也需要推出自己开发的应用软件,如小米( Mi OpenSource github 开源社区)开源的小米便签,我们的程序就是属于这一层。
-
Java API 框架
您可通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务:
- 丰富、可扩展的视图系统,可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器
- 资源管理器,用于访问非代码资源,例如本地化的字符串、图形和布局文件
- 通知管理器,可让所有应用在状态栏中显示自定义提醒
- Activity 管理器,用于管理应用的生命周期,提供常见的导航返回栈
- 内容提供程序,可让应用访问其他应用(例如“联系人”应用)中的数据或者共享其自己的数据
开发者可以完全访问 Android 系统应用使用的框架 API。
吃瓜:关于Google和oracle的 Java SE之争自行百度或谷歌。
-
系统运行库
原生 C/C++ 库
许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。例如,您可以通过 Android 框架的 Java OpenGL API 访问 OpenGL ES,以支持在应用中绘制和操作 2D 和 3D 图形。如果开发的是需要 C 或 C++ 代码的应用,可以使用 Android NDK 直接从原生代码访问某些原生平台库。
Android Runtime
对于运行 Android 5.0(API 级别 21)或更高版本的设备,每个应用都在其自己的进程中运行,并且有其自己的 Android Runtime (ART) 实例。ART 编写为通过执行 DEX 文件在低内存设备上运行多个虚拟机,DEX 文件是一种专为 Android 设计的字节码格式,经过优化,使用的内存很少。编译工具链(例如 Jack)将 Java 源代码编译为 DEX 字节码,使其可在 Android 平台上运行。
ART 的部分主要功能包括:
- 预先 (AOT) 和即时 (JIT) 编译
- 优化的垃圾回收 (GC)
- 更好的调试支持,包括专用采样分析器、详细的诊断异常和崩溃报告,并且能够设置监视点以监控特定字段
在 Android 版本 5.0(API 级别 21)之前,Dalvik 是 Android Runtime。如果您的应用在 ART 上运行效果很好,那么它应该也可在 Dalvik 上运行,但反过来不一定。
Android 还包含一套核心运行时库,可提供 Java API 框架使用的 Java 编程语言大部分功能,包括一些 Java 8 语言功能。
-
硬件抽象层 (HAL)
硬件抽象层 (HAL) 提供标准界面,向更高级别的 Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机或蓝牙模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。
-
Linux 内核
Android 平台的基础是 Linux 内核。例如,Android Runtime (ART) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。使用 Linux 内核可让 Android 利用主要安全功能,并且允许设备制造商为著名的内核开发硬件驱动程序。
总结:架构是为了需求场景服务,而 Android 的架构正是为了更好地满足硬件设备厂商、开发者以及用户而设计的。架构设计又不一定是整个应用或者系统的设计,也可以是一个模块或者一个需求的设计。架构设计能力的成长是建立在一个又一个坑、一次又一次的重构之上。
平台架构、Android 整体设计及背后意义
-
应用演进
- 移动端跨平台技术
从最开始依赖于 WebView 的 Hybrid 混合开发技术,到 React Native 的桥接( 将 JS 转为 Native)的技术,再到最新的 Flutter 技术。
在大前端方向,对于跨平台开发中一直在不断迭代中寻找更好、更优的解决方案,目前来看 Flutter 还是更有优势。
总结:无论我们使用哪一种跨平台方案,它们最终都要运行在 Android 平台上。崩溃、内存、卡顿、耗电这些问题依然存在,而且可能会更加复杂。
Flutter中文网
- 应用架构
MVC 模式(Model–view–controller) 但Activity类过于臃肿,为解决这个问题,有了 MVP(Model–view–presenter),presenter 不仅要操作数据,而且要更新 view;再到 MVVM(Model-View-ViewModel)解决了 MVP 大量的手动 View 和 Model 同步的问题,提供双向绑定机制。
总结:好的程序架构是一步步迭代的出来的
- 热修复与插件化技术
热修复的主要应用场景是为了让用户无感得修复线上缺陷,比如 Tinker,Andfix 等。插件化是为了减少模块耦合,可减少主程序的规模,可按需加载,比如 DroidPlugin 等。
Android 7.0 对 Native 的 NDK 的调用限制是手铐,尤其是 Android 9.0 对 Java 层 SDK 的调用限制就是脚铐,那么对于 Android 应用想再搞插件化之类的黑科技便是带着脚手铐跳舞,能跳但舞姿可能不太美观。
总结:热修复、插件化给国内的 Android 生态也带来一些不太好的影响,总归只是顺应潮流的变化,但是技术方向是可以去学习借鉴的。
移动开发的罗曼蒂克消亡史、由VirtualAPK了解插件化原理(一)、由VirtualAPK了解插件化原理(二)、由Tinker了解热修复原理
- Kotlin
是 Google 推荐的官方静态编程语言,与 Java 互通,可相互转换。Kotlin 编译成 Java 字节码,也可以编译成 JavaScript,运行在没有 JVM 的设备上,简洁安全。使用 Kotlin 更快速地编写 Android 应用,可以提高开发者的工作效率,少编写样板代码,被称之为 Android 世界的 Swift。谷歌开发者社区做过一个问卷调查,大概有40%的 Android 开发者已使用过 Kotlin。这里并非鼓励大家一定都要使用 Kotlin,学习新语言就像一次投资,要权衡团队成本与收益之间的利弊。
Kotlin中文网
Android进程间通信
Android 系统是基于 Linux 内核的,Linux 已经提供了管道、消息队列、共享内存和 Socket 等 IPC 机制。但 Android 也实现了自己的进程间通信机制 Binder,下图从三个角度解释 Android 为何要自己实现 Binder 机制。
跨进程通信是需要内核空间做支持的。传统的 IPC 机制如管道、Socket 都是内核的一部分,因此通过内核支持来实现进程间通信自然是没问题的。但是 Binder 并不是 Linux 系统内核的一部分,它依赖于 Linux 的动态内核可加载模块(Loadable Kernel Module,LKM)的机制;模块是具有独立功能的程序,它可以被单独编译,但是不能独立运行。它在运行时被链接到内核作为内核的一部分运行。这样,Android 系统就可以通过动态添加一个内核模块运行在内核空间,用户进程之间通过这个内核模块作为桥梁来实现通信。
一次完整的 Binder IPC 通信过程通常是这样:
- 首先 Binder 驱动在内核空间创建一个数据接收缓存区;
- 接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系;
- 发送方进程通过系统将数据 copy 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。
Binder 是基于 C/S 架构的。由一系列的组件组成,包括 Client、Server、ServiceManager、Binder 驱动。其中 Client、Server、Service Manager 运行在用户空间,Binder 驱动运行在内核空间。其中 Service Manager 和 Binder 驱动由系统提供,而 Client、Server 由应用程序来实现。Client、Server 和 ServiceManager 均是通过系统调用 open、mmap 和 ioctl 来访问设备文件 /dev/binder,从而实现与 Binder 驱动的交互来间接的实现跨进程通信。
- 从进程间通信的角度看,Binder 是一种进程间通信的机制;
- 从 Server 进程的角度看,Binder 指的是 Server 中的 Binder 实体对象;
- 从 Client 进程的角度看,Binder 指的是对 Binder 代理对象,是 Binder 实体对象的一个远程代理
- 从传输过程的角度看,Binder 是一个可以跨进程传输的对象;Binder 驱动会对这个跨越进程边界的对象对一点点特殊处理,自动完成代理对象和本地对象之间的转换。
写给 Android 应用工程师的 Binder 原理剖析、源码解读Binder机制
更多文章
Android线程间通信
Java端流程图
内部实现原理:epoll机制:epoll_create、epoll_ctl、epoll_wait、close
Handler源码解读、都 2021 年了,还有人在研究 Handler?
更多文章
Android系统启动流程
-
启动电源以及系统启动
当电源键按下时引导芯片代码从预定义的地方(固化在 ROM )开始执行。加载引导程序 BootLoader 到 RAM 中,然后执行。
-
引导程序 BootLoader
引导程序 BootLoader 是在 Android 操作系统开始运行前的一个小程序,它的主要作用是把系统 OS 拉起来并运行。
-
Linux内核启动
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置时,它首先在系统文件中寻找 init.rc 文件,并启动 init 进程。
-
init 进程启动
init 进程会初始化属性服务,并且解析 init.rc 文件,启动 zygote 进程
init 进程是Android系统中用户控件的第一个进程,进程号是 1。
整个启动过程做了很多工作,不过总的来说分为以下三个部分:
- 创建和挂载启动所需的文件目录
- 初始化和启动属性服务
- 解析 init.rc 配置文件并启动 Zygote 进程
-
Zygote 进程启动
创建 java 虚拟机并为 java 虚拟机注册 JNI 方法,创建服务器端 Socket,启动 SystemServer 进程。
在 Android 系统中,DVM 和 ART、应用程序进程以及运行系统的关键服务的 SystemServer 进程都是由 Zygote 进程来创建的,我们也将它称为孵化器。
总结一波在这里 zygote 究竟干了什么:
- 创建 AppRuntime 对象并调用它的 start 方法,启动 zygote 进程,此后的操作活动由 AppRuntime来控制。
- 调用 startVm 创建 Java 虚拟机,调用 startReg 来注册 JNI 函数。
- 通过 JNI 调用 com.android.internal.os.ZygoteInit下的 main 函数,初始化整个 Java 层。
- 通过 registerZygoteSocket 函数创建服务端 Socket,并通过 runSelectLoop 函数等待 ActivityManagerService 的请求来创建新的应用程序进程。
- 启动 SystemServer 进程。
-
SystemServer进程启动
启动 Binder 线程池和 SystemServiceManager,并且启动各种系统服务。
SystemServer 进程主要用于创建系统服务,我们熟知的 AMS、WMS 和 PMS 都是由它来创建的。
SystemServer 主要工作为下面三个方面:
- 启动 Binder 线程池
- 创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理
- 启动各种系统服务
-
Launcher启动
AMS 启动 Launcher,Launcher 被启动后会将已安装的应用图片显示在界面上。
Android操作系统启动过程概览、 SystemServer源码分析、Zygote进程启动过程
Android App 启动流程
Android UI 显示
应用程序图形渲染过程当作一次绘画过程,那么绘画过程中 Android 的各个图形组件的作用是:
- 画笔:Skia 或者 OpenGL。我们可以用 Skia 画笔绘制 2D 图形,也可以用 OpenGL 来绘制 2D/3D 图形。正如前面所说,前者使用 CPU 绘制,后者使用 GPU 绘制。
- 画纸:Surface。所有的元素都在 Surface 这张画纸上进行绘制和渲染。在 Android 中,Window 是 View 的容器,每个窗口都会关联一个 Surface。而 WindowManager 则负责管理这些窗口,并且把它们的数据传递给 SurfaceFlinger。
- 画板:Graphic Buffer。Graphic Buffer 缓冲用于应用程序图形的绘制,在 Android 4.1 之前使用的是双缓冲机制;在 Android 4.1 之后,使用的是三缓冲机制。
- 显示:SurfaceFlinger。它将 WindowManager 提供的所有 Surface,通过硬件合成器 Hardware Composer 合成并输出到显示屏。
推荐
android开发者文档、Android开发者网站
官网
C++ 参考手册
c++ 、 c 参考网站
Jdk源码
Java 在线源码阅读
AOSP、在线阅读
源码
github
不多介绍
wanandroid
我经常访问的一个网站
Kotlin中文网、Flutter中文网
国内大牛们所建的网站,有能力当然建议阅读英文
如何打造高质量的应用?
-
一个应用至少会经过开发、编译 CI、测试、灰度和发布这几个阶段
-
应用性能的监控平台