Day946.厂商定制的Android系统为什么也要解耦? -系统重构实战

news2024/11/19 22:44:48

厂商定制的Android系统为什么也要解耦?

Hi,我是阿昌,今天学习记录的是关于厂商定制的Android系统为什么也要解耦?的内容。

一、Android 系统架构

AOSP,全称是 Android Open Source Project,中文译为“Android 开放源代码项目”。

厂商每年会基于 Google 开放的最新代码进行适配定制,开发属于自己的 OS 版本。

首先,根据 Android 的架构图来看看 Android 系统架构的设计。

在这里插入图片描述

对照架构图,从上到下来看。

在应用框架层上面应该还有一层,就是诸多的应用。

这些应用可以分为 2 类:

  • 一类是系统应用,拥有高的系统权限,可以调用系统提供的高权限接口,例如打电话、短信、设置等应用;
  • 另外一类就是非系统应用,与第三方应用一样,例如定制一些便签、运动健康、视频播放等应用。

  • 第一层就是应用框架层,应用框架最常被应用开发者使用,对应用提供标准的 API 来调用系统的能力,从而实现相关的业务功能。我们在代码编译时,通常会依赖 Android SDK 的 android.jar 空包,保证能通过编译。但需要注意的是 android.jar 具体的实现都在框架层中,实际运行时调用的都是系统中的类。

  • 第二层是 Binder IPC。有了 Binder 进程间通信 (IPC) 机制,应用框架就能跨越进程边界并调用 Android 系统服务代码。由于系统的很多服务都是运行在 System Server 进程,但是集成到应用的 SDK 代码是运行在应用的进程,所以需要通过 Binder 的方式来实现跨进程间的通信。

  • 第三层是系统服务层。系统服务专注于特定功能的模块化组件,例如窗口管理器、搜索服务或通知管理器。例如熟悉的 AMS、WMS、PMS 等,都运行在系统服务层。

  • 第四层是硬件抽象层 (HAL)。Google 在 Android 8.0 里一个名为“Treble”的项目中设计了 HAL 层,目的是让制造商能够以更低成本、更轻松快速地将设备更新到新版 Android 系统。在这种新架构中,HAL 接口定义语言指定了 HAL 和其用户之间的接口,让用户无需重新构建 HAL,就能替换 Android 框架。

  • 最后一层是 Linux 内核层。Google 在官网介绍的开发 Android 设备驱动程序与开发典型的 Linux 设备驱动程序类似。但 Android 使用的 Linux 内核版本包含一些特殊的补充功能,例如低内存终止守护进程、唤醒锁定、Binder IPC 驱动程序等,对于移动嵌入式平台,这些是非常重要的功能。

二、对 Anroid 系统的“魔改”

既然 Android 系统已经有了规范的架构设计,为什么定制 Android 系统还会产生耦合的问题呢?

由于手机产品涉及软硬结合,所以一般会采用 IPD 产品开发流程,研发一款手机的时间通常需要 3 - 12 个月的时间,并按

1、应用之间的耦合

理论上来说,应用之间都是相对独立的。但是在定制系统中,有一些应用在运行时存在相互依赖,例如桌面与负一屏(基于桌面向右滑动后的快捷入口)。

这里应用 A 在运行时可能需要调用应用 B 提供的某些方法,才能保证功能正常运行,如下图所示。

在这里插入图片描述

这里看起来似乎合理,编译上没有依赖,运行时也是通过标准的 API 调用。但关键的问题是不同项目上的功能有差异,依赖的 API 会有变化,并且应用之间并没有做好兼容性的处理,这样导致应用 B 不存在时,应用 A 无法正常运行。

结合下图来理解:

在这里插入图片描述


2、应用与框架之间的耦合

应用与框架之间的耦合。做过应用开发的同学应该知道,我们需要依赖 Android 的 SDK 来开发。因为 Google 会保持 SDK 接口的稳定及兼容,所以基于标准 SDK 开发的应用,才能运行在各个大版本的 Android 系统中。但是在框架里面还有一些类被标识了 @hide,或者有些类属于 com.android.internal 中的类,这些都是标准的 SDK 不会提供的。但是,厂商可以编译生成完整的 android.jar 包,这样应用就可以调用到这些非公开的接口,以便实现更加丰富的功能。

当然还有一些应用采用另外一种方法,就是使用反射的形式

可以结合后面的示意图来理解。

在这里插入图片描述

由于这部分 API,Google 在大版本的迭代中并不一定保证兼容,所以这也意味着一旦使用这个特殊的 Jar 包的应用,就与特定的大版本绑定了。应用需要针对每一个大版本都维护一个特定的 APK。

遇到过一种更“反直觉”的操作——框架依赖应用。比如在框架层增加代码,会去调用 APP 中相关的资源及代码。

这种反向的耦合更容易出现问题,因为一旦底层框架代码的兼容性没有处理好,就很容易导致无法开机、黑屏等严重后果。### 场景 3:框架之间的耦合第三种典型的耦合场景是框架之间的耦合,这里的框架耦合指的是厂商扩展的代码与框架之间的耦合。

为了扩展系统的功能,定制 Android 系统可以在框架中添加一些代码,例如可以在 AMS 里面的 Activity 生命周期回调增加一些统计代码,就能统计到应用界面的一些执行情况。

这些能力是三方应用无法实现的功能,是厂商定制应用的优势。

可以参考后面的示意图来理解。

在这里插入图片描述

但是缺少规范化的管理及灵活的插桩设计,也会产生耦合问题。我

Google 每年都会更新 AOSP 基线代码,框架之间的耦合会导致扩展的代码与框架代码强关联。

  • 一方面这些代码只能跟随着框架代码一起维护,无法做到独立维护;

  • 另外一方面当代码有更新时,维护成本也非常高


三、耦合带来的问题

除了前面提到的定制 Android 系统的耦合问题,耦合也会影响到团队效率以及产品质量,接下来就重点探讨三个常见问题。

1、大量重复的代码合并工作

前面提到 Google 每年都会升级一个 Android 的大版本,对于厂商来说,他们其实拿到的是第三手代码。

前面还有一个上游——芯片平台

为了帮助理解,这张示意图。

在这里插入图片描述

因为是第三手代码,为了保证本地代码能及时同步上游的最新代码,厂商需要定期去同步上游的代码,大版本可能是每年一次,补丁 Patch 可能是 2 周一次。

由于侵入性的修改,容易导致代码冲突的出现,特别是每次的大版本更新。

另外,由于各种耦合的问题,通常最后量产版本时需要拉去独立的 MP 分支。

这样,并行的项目越多时,合并代码的工作量就会呈指数级爆发。


2、并行维护多个版本

由于应用于架构和耦合问题,会让不同项目集成难度升高。

因为应用无法做到一个 apk 适配多个项目,这样对于应用来说往往需要同时维护 3-5 个版本,并且通常也是采用拉取分支的形式,一个分支出一个项目版本的 APK。

在这里插入图片描述

同时,维护多个版本带来了大量重复性的工作。

例如当修复一个 Bug 时,需要同步到若干个分支中,并且带给测试同学的压力也非常大。

由于每个分支的代码都不是完全一致的,需要做回归测试时,工作量也会翻倍。


3、“未知”的产品质量

由于代码的耦合问题,非常容易导致修改代码出现连带问题。所以开发同学会选择尽可能少修改代码,更别谈去做一些中大型的代码重构。

在机型数量越来越多的状态下,技术复杂度越来越高。

两种压力的共同作用下,代码修改越多,代码重构就变得越来越难,代码质量完全无法把控。

另外,对于产品的质量也带来了非常大的挑战。

前面提到的多项目、多版本的问题,导致在最后集成阶段需要大量的回归测试,然而在缺乏高质量的自动化测试覆盖下,仅靠人工很难进行全面的验证,这样就非常容易导致问题流到线上用户手中。


四、总结

各个分层职责清晰,从上到下依次为应用框架层、Binder IPC、系统服务层、硬件抽象层以及 Linux 内核层。但是当厂商开始定制 Android 系统时,由于项目管理、交付压力等等情况,非常容易出现不按规矩出牌的情况,总结了 3 种最常见的耦合场景,后面的表格回顾。

在这里插入图片描述

由于耦合的问题,团队需要完成大量重复、机械性的代码合并工作,也需要同时维护多个并行的版本。

开发同学淹没在数不尽的分支合并任务里,测试同学淹没在数不尽的黑盒测试中,团队无法把精力投入到代码优化和更多产品质量优化工作上,时间一久,就会给系统埋下诸多隐患。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/444600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

永磁同步电机流频比(I/F)控制及Matlab/Simulink仿真分析

文章目录 前言一、流频比I/F控制原理二、永磁同步电机I/F控制系统Matlab/Simulink仿真分析2.1.仿真电路分析2.1.1 I/F控制算法2.1.2 电流环2.1.3 输出处理2.1.4 主电路 2.2 仿真结果分析 总结 前言 本章节采用流频比I/F控制方法驱动永磁同步电机的转动,首先分析流频…

传统机器学习(二)逻辑回归算法(一)

传统机器学习(二)逻辑回归算法(一) 1.1 算法概述 1.1.1 逻辑回归及其梯度推导 ​ 线性回归的任务,就是构造一个预测函数来映射输入的特征矩阵x和标签值y的线性关系,而构造预测函数的核心就是找出模型的参数,著名的最小二乘法就是用来求解线性回归中参…

J-Link不能连接目标MCU几点常见原因

J-Link是嵌入式软件最常用的工具之一,但是,在使用这个工具时,也会遇到各种各样的问题。 J-Link的连接 使用J-Link,首先第一步硬件连接,确认J-Link和PC机之间是否连接正常,并确认上位机能和 J-Link 建立正…

ZedGraph 绘制动态曲线

文章目录 前言:开发环境:1 下载ZedGraph 控件并设置图形界面2 功能实现3 需求升级4 小结 话不多数,先上一个效果图: 前言: 需要采集一些设备的数据以图表的形式展示出来,研究数据的走向是否平稳&#xff0…

mac Homebrew方式安装 activemq

两种方式安装 activemq 一、通过Homebrew管理安装 1. 确保homebrew可用 查看brew版本 brew -v 如果报错,则可能是未启用brew,需要安装或更新 更新并重新查看是否安装成功 brew update brew -v 2. 安装 activemq:下载activemq前 会先下载相…

Direct3D 12——纹理——寻址模式

可将经过常数插值或线性插值的纹理定义为一个返回向量值的函数T(u, v) (r,g,b,a),即给 定纹理坐标(u,v)∈[0,1]^2,则上述纹理函数T将返回颜色(r,g, b, a)。 Direct3D允许…

MLCC周期性分析:当前时点处于周期反转前夜

MLCC是电子工业大米,供需波动导致行业成周期性波动 MLCC是最常用的被动元器件之一,终端下游涵盖消费电子、家电、汽车、通信等。在5g、汽车电子、智能硬件的推动下,MLCC行业需求稳步增长。供给端来看,中国大陆厂商合计市场份额不…

MFC加载动态gif图片文件C++语言,基于MFC的动画播放控件

MFC加载动态gif图片,使用VS2015环境 一、将下载的PictureEx.h和PictureEx.cpp放在工程文件的目录下,动态gif图片放在工程文件的res文件夹下;(GIF动图下载 https://icons8.com/preloaders/en/search/move) &#xff08…

企业级VUE前端项目各目录文件的作用

概述 本文项目是基于Vue CLI3构建工具(基于 webpack)生成的脚手架项目。Vue CLI 现已处于维护模式,VUE官方推荐使用 create-vue(基于 Vite)构建工具。 vue-cli2.0与3.0在目录结构方面,有明显的不同,vue-cli3.0移除了…

Linux性能优化实战

1. TCP/IP报文详解 TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。TCP负责发现传输的问题,一有问题就发出信号,要求重…

根据cadence设计图学习硬件知识day04了解一些芯片

1.PI3PCIE3212 (双向信道多路复用器/多路分解器开关) PI3PCIE3212是PCIe Gen3.0、8Gbps、4对2差分,PCI ExpressR 3.0性能,8.0Gbps 双向信道多路复用器/多路分解器开关。由于其低的位对位偏斜,高的通道对通道噪声隔离…

邂逅Node.js开发

目录: 1 Node.js是什么? 2 Node的应用场景 3 Node安装和管理 4 JavaScript代码执行 5 Node的输入和输出 6 Node的全局对象 node命令是可以直接运行js脚本的,在某文件夹底下只要有js文件,就可以通过命令提示符运行该js文件。格式是 &…

简单聊聊煤炭行业的数字化和可持续发展

煤在普通人的心目中是一种能引起复杂感情的东西。我们喜欢它在冬天给我们带来温暖,我们不喜欢它因为它黢黑黢黑的,沾在身上特别黑,看起来脏兮兮的。在笔者的记忆中,小时候煤可是生活的必需品。 小时候在冬天的河北必须要生炉子&a…

电源常识-纹波-EMI

1、纹波﹔纹波就是一个直流电压中的交流成分。直流电压本来应该是一个固定的值,但是很多时候它是通过交流电压整流、滤波后得来的,如图1,由于滤波不彻底,就会有剩余的交流成分,即使采用电池供电也会因负载的波动而产生波纹。事实上…

FreeRTOS 任务相关 API 函数

FreeRTOS 中用于创建和删除任务的 API 函数如下表所示: 1. 函数 xTaskCreate() 此函数用于使用动态的方式创建任务,任务的任务控制块以及任务的栈空间所需的内存, 均由 FreeRTOS 从 FreeRTOS 管理的堆中分配,若使用此函数&#x…

聚焦慕思欧洲设计中心,用设计谱写健康睡眠新篇章

4月20日,在意大利米兰,多位欧洲顶尖设计师齐聚ADI博物馆,共同见证“梦享之美”——慕思欧洲设计中心暨设计国际梦之队成立发布会的盛大召开。慕思此次发布会特地选定在米兰国际家具展期间,而这是公认的世界三大家具展之一&#xf…

DF竞赛平台携手嬴彻科技与清华大学智能产业研究院,助力自动驾驶挑战赛圆满落幕!

由DataFountain竞赛平台(简称DF平台)提供办赛支持的「首届“嬴彻-清华AIR杯”自动驾驶挑战赛:决策规划算法」已圆满落幕。作为一场前沿性自动驾驶类比赛,本次大赛立足“高速道路”和“城市道路”两大真实场景,选择“半…

SEO文章批量生成

SEO文章生成器 想必大部分人对于 SEO 这个词不会陌生,它是指一系列的优化策略,目的是让网站能够在搜索引擎上更容易地被检索,并获得更多的流量和曝光度。但是,SEO 的优化并非易事,尤其对于那些没有相关技术知识和经验…

科技云报到:存储开源,风雨飘摇下“披着羊皮的狼”?

科技云报道原创。 这些年开源界的风风雨雨,时不时撼动着人们的内心。 2022年,俄乌冲突导致全球最大的独立开源软件公司SUSE、美国开源软件巨头Redhat、主流开源容器引擎Docker,纷纷宣布停止与俄罗斯的合作。 而全球最大的开源及私有代码项目…

react-8 Redux 状态管理 - 持久化存储 => 进阶:React-Redux()和模块化

1.redux redux是独立于react的库,是js状态管理库,提供可预测的状态管理。Vue也可用,但是和react比较搭配 。 2. 什么时候用 redux? 解决:任意:多组件共享状态, 解决:任意:两个…