给 Android 开发者的第一堂课

安卓(Android)是一种基于 Linux 内核(不包含 GNU 组件)的自由及开放源代码的操作系统。主要使用于移动设备,如智能手机和平板电脑,由美国 Google 公司和 开放手机联盟 领导及开发。Android 操作系统最初由 Andy Rubin 开发,主要支持手机。2005年8月由 Google 收购注资。2007年11月,Google 与84家硬件制造商、软件开发商及电信营运商组建开放手机联盟共同研发改良 Android 系统。随后 Google 以 Apache 开源许可证的授权方式,发布了 Android 的源代码。第一部 Android 智能手机发布于2008年10月。Android逐渐扩展到平板电脑及其他领域上,如电视、数码相机、游戏机、智能手表等。

Android 的架构

  1. 系统演进
  • 从 Android 1.0 发展到 Android 4.0,系统各项功能和特性迭代到一个较完善的阶段;
  • Android 4.1 系统,Google 开展了黄油计划(Project Butter),为了让 Android 系统摆脱 UI 交互上的严重滞后感,希望能像“黄油”一样顺滑。 核心原理是系统框架中的渲染和动画统一采用垂直同步技术(VSYNC),以及三重缓冲技术(Triple Buffer),让滑动、翻页等操作更加一致与顺滑。

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开发者文档
  1. 整体架构

整体架构图

  1. 应用程序

Android 随附一套用于电子邮件、短信、日历、互联网浏览和联系人等的核心应用。平台随附的应用与用户可以选择安装的应用一样,没有特殊状态。因此第三方应用可成为用户的默认网络浏览器、短信 Messenger 甚至默认键盘(有一些例外,例如系统的“设置”应用)。
系统应用可用作用户的应用,以及提供开发者可从其自己的应用访问的主要功能。例如,如果您的应用要发短信,您无需自己构建该功能,可以改为调用已安装的短信应用向您指定的接收者发送消息。
国内各大厂商在修改 Framewort 时也需要推出自己开发的应用软件,如小米( Mi OpenSource github 开源社区)开源的小米便签,我们的程序就是属于这一层。

  1. Java API 框架

您可通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务:

  • 丰富、可扩展的视图系统,可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器
  • 资源管理器,用于访问非代码资源,例如本地化的字符串、图形和布局文件
  • 通知管理器,可让所有应用在状态栏中显示自定义提醒
  • Activity 管理器,用于管理应用的生命周期,提供常见的导航返回栈
  • 内容提供程序,可让应用访问其他应用(例如“联系人”应用)中的数据或者共享其自己的数据
    开发者可以完全访问 Android 系统应用使用的框架 API。

吃瓜:关于Google和oracle的 Java SE之争自行百度或谷歌。

  1. 系统运行库
原生 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 语言功能。
  1. 硬件抽象层 (HAL)

硬件抽象层 (HAL) 提供标准界面,向更高级别的 Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机或蓝牙模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。

  1. Linux 内核

Android 平台的基础是 Linux 内核。例如,Android Runtime (ART) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。使用 Linux 内核可让 Android 利用主要安全功能,并且允许设备制造商为著名的内核开发硬件驱动程序。

总结:架构是为了需求场景服务,而 Android 的架构正是为了更好地满足硬件设备厂商、开发者以及用户而设计的。架构设计又不一定是整个应用或者系统的设计,也可以是一个模块或者一个需求的设计。架构设计能力的成长是建立在一个又一个坑、一次又一次的重构之上。

平台架构Android 整体设计及背后意义

  1. 应用演进
  • 移动端跨平台技术
    从最开始依赖于 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 同步的问题,提供双向绑定机制。
总结:好的程序架构是一步步迭代的出来的
  • 热修复与插件化技术
    热修复的主要应用场景是为了让用户无感得修复线上缺陷,比如 TinkerAndfix 等。插件化是为了减少模块耦合,可减少主程序的规模,可按需加载,比如 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 机制。
Binder优势

进程间通信原理图

跨进程通信是需要内核空间做支持的。传统的 IPC 机制如管道、Socket 都是内核的一部分,因此通过内核支持来实现进程间通信自然是没问题的。但是 Binder 并不是 Linux 系统内核的一部分它依赖于 Linux 的动态内核可加载模块(Loadable Kernel Module,LKM)的机制;模块是具有独立功能的程序,它可以被单独编译,但是不能独立运行。它在运行时被链接到内核作为内核的一部分运行。这样,Android 系统就可以通过动态添加一个内核模块运行在内核空间,用户进程之间通过这个内核模块作为桥梁来实现通信。

一次完整的 Binder IPC 通信过程通常是这样

  1. 首先 Binder 驱动在内核空间创建一个数据接收缓存区
  2. 接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系
  3. 发送方进程通过系统将数据 copy 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。

一次完整的 Binder IPC 通信过程

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 驱动会对这个跨越进程边界的对象对一点点特殊处理,自动完成代理对象和本地对象之间的转换。

Binder 基类数据 bwr 结构图

完整流程图

写给 Android 应用工程师的 Binder 原理剖析源码解读Binder机制
更多文章

Android线程间通信

Java端流程图Java端流程图

请添加图片描述

内部实现原理:epoll机制:epoll_create、epoll_ctl、epoll_wait、close
Handler源码解读都 2021 年了,还有人在研究 Handler?
更多文章

Android系统启动流程

Android系统启动流程

  1. 启动电源以及系统启动

当电源键按下时引导芯片代码从预定义的地方(固化在 ROM )开始执行。加载引导程序 BootLoader 到 RAM 中,然后执行。

  1. 引导程序 BootLoader

引导程序 BootLoader 是在 Android 操作系统开始运行前的一个小程序,它的主要作用是把系统 OS 拉起来并运行

  1. Linux内核启动

当内核启动时,设置缓存被保护存储器计划列表加载驱动。当内核完成系统设置时,它首先在系统文件中寻找 init.rc 文件,并启动 init 进程。

  1. init 进程启动

init 进程会初始化属性服务,并且解析 init.rc 文件,启动 zygote 进程

init 进程是Android系统中用户控件的第一个进程,进程号是 1。
整个启动过程做了很多工作,不过总的来说分为以下三个部分:

  • 创建和挂载启动所需的文件目录
  • 初始化和启动属性服务
  • 解析 init.rc 配置文件并启动 Zygote 进程
  1. 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 进程
  1. SystemServer进程启动

启动 Binder 线程池和 SystemServiceManager,并且启动各种系统服务。
SystemServer 进程主要用于创建系统服务,我们熟知的 AMSWMSPMS 都是由它来创建的。

SystemServer 主要工作为下面三个方面:

  • 启动 Binder 线程池
  • 创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理
  • 启动各种系统服务
  1. Launcher启动

AMS 启动 Launcher,Launcher 被启动后会将已安装的应用图片显示在界面上
Launcher启动

Android操作系统启动过程概览SystemServer源码分析Zygote进程启动过程

Android App 启动流程

Android App 启动流程

Android UI 显示

Android UI 显示

应用程序图形渲染过程当作一次绘画过程,那么绘画过程中 Android 的各个图形组件的作用是:

  1. 画笔:Skia 或者 OpenGL。我们可以用 Skia 画笔绘制 2D 图形,也可以用 OpenGL 来绘制 2D/3D 图形。正如前面所说,前者使用 CPU 绘制,后者使用 GPU 绘制
  2. 画纸:Surface。所有的元素都在 Surface 这张画纸上进行绘制和渲染。在 Android 中,Window 是 View 的容器,每个窗口都会关联一个 Surface。而 WindowManager 则负责管理这些窗口,并且把它们的数据传递给 SurfaceFlinger
  3. 画板Graphic Buffer。Graphic Buffer 缓冲用于应用程序图形的绘制,在 Android 4.1 之前使用的是双缓冲机制;在 Android 4.1 之后,使用的是三缓冲机制。
  4. 显示:SurfaceFlinger。它将 WindowManager 提供的所有 Surface,通过硬件合成器 Hardware Composer 合成并输出到显示屏

推荐

android开发者文档Android开发者网站
官网
C++ 参考手册
c++ 、 c 参考网站
Jdk源码
Java 在线源码阅读
AOSP在线阅读
源码
github
不多介绍

wanandroid
我经常访问的一个网站
Kotlin中文网Flutter中文网
国内大牛们所建的网站,有能力当然建议阅读英文

如何打造高质量的应用?

  1. 一个应用至少会经过开发、编译 CI、测试、灰度和发布这几个阶段
    请添加图片描述

  2. 应用性能的监控平台

请添加图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值