【AICon】探索八个行业创新案例,教你在教育、金融、医疗、法律等领域实践大模型技术! >>> 了解详情
写点什么

爱奇艺 App 架构升级之路——64 位适配探索与实践

  • 2020-08-17
  • 本文字数:3277 字

    阅读完需:约 11 分钟

爱奇艺App架构升级之路——64位适配探索与实践

背景

?随着手机硬件的不断发展,近两年的新式手机已经全部采用了 64 位 CPU,64 位真的比 32 位快吗?实际上 32 位和 64 位的差异主要体现在内存寻址上,32 位最高只支撑 4GB 内存,而 64 位则能够最高支撑 128GB 内存。

目前三星、华为、VIVO、OPPO 等手机厂商应用商店已经支持 32 位和 64 位,但尚未强制要求,然而从长远的 App 框架角度来看,64 位爱奇艺 App 给予的其实是更加广阔的创新空间,经过兼容更多更新的硬件来提高软件的全体性能,随着 64 位 CPU 逐步成新式手机的主流,针对适配 64 位的应用软件将越来越遍及。

1 64 位适配的原理

64 位适配,就是令 APP 在支持 64 位系统的设备上启动 64 位进程来运行。下面详细讲解一下如何让 APP 运行在 64 位进程上。


  1. Android 手机系统在启动的过程中,会根据设备的 ro.zygote 属性值决定启动哪类 Zygote。如果是支持 64 位系统的设备,会有两个 Zygote(一个 32 位,一个 64 位)进程同时运行。

  2. 在 APP 安装的过程中,PMS 里面的 scanPackageDirtyLI 方法通过遍历 APK 文件夹里面的 lib 下面的 so 库根目录,再结合该手机硬件支持的 abilists 列表,来决定 primaryCpuAbi 的值,具体请参考下图 2-1 的时序图:

  3. 在 APP 启动的过程中,AMS 根据前面得到的 primaryCpuAbi 的值作为参考,通过调用 Process 的 start()方法来确定,该 APP 是从 64 位还是 32 位的 Zygote 进程 fork 出子进程。如果子进程来自 64 位 Zygote,该 APP 就运行在 64 位进程。



举个例子:假如 APK 里面的 so 库有 armeabi-v7a 和 arm64-v8a 这两个目录,而某一个手机硬件支持的 abilists 是 armeabi,armeabi-v7a,arm64-v8a;这时候,primaryCpuAbi 的取值就是 arm64-v8a;那么当 APP 启动后,就会运行在 64 位进程。


由此见得,64 位适配的重点在应用端就是 so 库的适配。下面详细介绍一下爱奇艺 APP 在 so 库适配上的实践。

2 so 库的适配

APP 里面 so 库的存在方式有三种:一种是 APK 里面自带的静态 so 库;另一种是通过插件中心加载的插件内的 so 库;第三种是动态下发的 so 库。下面分别介绍一下这三种情况的适配。

2.1 APK 里面 so 库的适配

APK 里面的 so 库有两种适配方案:


方案一,这种是比较粗暴的,即构建一个支持所有的 ABI 类型的 APK,优点是可以满足任意机型的安装,缺点是包体积可能变得非常大。


方案二,这种是比较轻量级的,即为每个 ABI 类型都单独构建一个 APK,不同 ABI 类型的设备安装对应的 APK,前提条件是应用市场需要根据用户的手机设备 ABI,下发对应合适的 APK 包,目前 Google Play 和国内应用市场都是支持的。

2.2 插件内的 so 库的适配

不管是通过何种方式实现的插件化,插件 APK 里面都可能会包含 so 库。插件里面的 so 库加载有三种方案:


方案一,提供包含所有 ABI 类型 so 库的插件包,由插件中心根据 APP 运行的进程情况来加载对应的 so 库;


方案二,提供多个包含不同 ABI 架构的插件包;插件中心在下载的时候,再决定下载哪一种对应的插件 APK;


方案三,提供一个基础的不包含 so 库的 base 插件包,再把每种 CPU 架构的 so 库生成一个 APK,插件中心最后下载 base 插件包以及对应 ABI 类型的 so 库文件;


目前爱奇艺插件化适配采用的是第二种方案,这里的插件中心就类似应用市场的角色。

2.3 云端下发的 so 库适配

客户端需要根据当前应用运行的进程情况,去获取相应类型的 so 库进行加载。针对云端下发的 so 库,我们专门设计了一个 so 分发管理平台来实现 64 位架构的适配。


so 分发管理平台分为两部分:前端 SDK 部分以及后端发布平台部分,架构设计图请参考下图:


2.3.1 前端 SDK 部分

前端在请求后端接口时,Request 会携带 APP 平台标识、APP 版本号以及运行时进程信息,获取接口配置数据,客户端根据应用运行状态下载包含对应 so 库的 zip 包,并解压到相应文件夹。流程图请参考下图:



*注意:客户端需要根据当前 APK 内置的 libs 目录和当前手机支持的 SUPPORT ABIs 共同决定运行时 ABI

1) 客户端 SDK 实现

So 库管理实现逻辑:客户端先加载本地缓存数据,同时拉取线上接口数据,两者数据合并之后,正确处理 so 实例对象状态,对于未安装的实例进行下载操作,下载完成后,依据业务方需要进行加载。具体的实现流程参考下图:


2)客户端 SDK 问题处理 so 库兼容性问题

定义了最低兼容版本号。当主 APP 发生升级时,线上的 so 库如果不兼容了,就必须强制卸载升级,防止加载了有问题的 so 库而导致崩溃;如果是向前兼容的,则可以继续使用上个版本的 so 库,而没有必要重新下载。


CPU 架构变化的处理


由于国内市场大部分还是支持 32 位的,爱奇艺 Android 客户端会长期存在 32 位和 64 位并行的情况。所以应用升级的时候,根据 APP 运行的是 32 位进程还是 64 位进程,升级到对应的 APK。升级之后,打开应用,加载云端 so 库的时候,就需要先判断 CPU 架构是否发生变化,如果发生变化,就直接抛弃所有的旧的 so 库,重新下载新的 so 库。


so 库文件损坏问题


so 库 zip 包的下载,跟其它网络文件下载一样,都有被劫持或者损坏的风险,所以需要提供校验,后端在 zip 包上传的时候生成对应的 md5 校验码,客户端下载后通过 md5 进行校验。而每次进入应用重新加载的时候,由于 so 库在可修改存储上面,也有可能被修改或者破坏掉,所以需要重新进行 so 库文件的校验,如果校验失败则重新解压或者重新下载。

2.3.2 后端发布平台部分

后端发布平台支持上传多种 ABI 类型的 so 库文件,后端接口根据前端上传的 APP 平台标识,APP 版本号和 APP 运行时进程信息,下发正确的 so 版本和下载地址给前端。后端发布平台 so 库上传如下图所示:


3 64 位适配优化

3.1. 升级及兼容性的优化

发现问题: 爱奇艺从 32 位升级到 64 位后,第一次进入 APP,加载了缓存中的 32 位的 so 库,导致 APP 崩溃。


优化策略: APP 启动后,每次客户端加载动态 so 库之前,要先根据 APP 的运行进程判断,缓存中的 so 库是否符合要求,如果不符合要求,直接删除已有的,重新下载及加载。

3.2. Tinker 热修复的优化

发现问题: 针对一个渠道对应多个包(32 位,64 位,32+64 位)的情况,如果一次打包只能产生一种类型的包,一个渠道多次打包肯定会导致同一渠道的多个包的 dex 是不一致的,这样热修的时候可能需要下发多个 patch。


优化策略: 为了简化流程,针对一个渠道 key,下发一个 patch。我们需要打包平台做一些处理,代码编译一次,先产生一个 32+64 位的包,然后对这个包进行处理,生成对应的 32 位包和 64 位包,之后重新签名 APK 文件即可。

3.3. 包体积在编译中的优化

如下是比较 common 的优化措施,可以优化编译效果,缩减编译后的 so 库大小:


  1. 添加-fvisibility=hidden 和-fvisibility-inlines-hidden 编译选项,这两个设置所用符号库默认 hidden,可减少大量 func 符号 string,优化效果明显

  2. 将编译选项-Os 改成-Oz,它主要是在-Os 的基础上禁用循环向量化优化,防止代码膨胀发生

  3. 加-flto 链接时优化编译选项,库大小优化效果比较明显

  4. 以及动态链接 c++_shared,也可以优化包体积


爱奇艺包体积编译参数经过优化,so 库的整体大小缩减了 10%左右。

实践总结

总体来说,爱奇艺 App 在 64 位全方位的适配之后,在性能方面有了一定的提升并且整体开播速度也有所提升。适配期间同时也遇到了一些问题,比如 64 位的适配过程中,插件适配方面原来采用的方案是插件 APK 里面支持多套 so 库,当时虽然能做到适配,但插件放 APK 较大,导致插件的分发成功率下降,以及爱奇艺的存储使用变大,然而通过后续的持续优化实现了支持多种 ABI 类型的插件 APK 的分发,并解决了上述的系列问题。


64 位适配的动态加载 so 库的适配过程中,代码各个模块的动态 so 库,有不同的后台,对应不同的下载路径,就需要各个业务方针对自己的 so 库做适配,其工作量和沟通成本巨大,为了解决这一问题则设计了一个统一的 so 库管理平台,各个业务模块可以直接对接 so 库管理平台,后续新的 so 库的接入,由 so 库管理平台来支持适配工作就可以完美支持了。


本文转载自公众号爱奇艺技术产品团队(ID:iQIYI-TP)。


原文链接


爱奇艺App架构升级之路——64位适配探索与实践


2020-08-17 10:063687

评论 2 条评论

发布
用户头像
文章写的很好哈
2020-08-17 18:05
回复
用户头像
爱奇艺那屎一样的客户端也能拿出来吹了?
2020-08-17 13:35
回复
没有更多了
发现更多内容

C++的重载运算符和重载函数

智趣匠

安全专家们看过来,易安联EnSRC第二期众测启动

权说安全

图文结合带你搞懂GreatSQL体系架构

GreatSQL

greatsql greatsql社区

快上车,搭乘HUAWEI HiCar驶向未来

HMS Core

HMS Core

推荐几款可以大幅提高开发效率的vscode插件 | 京东云技术团队

京东科技开发者

Vue 前端 vscode

G1垃圾回收参数调优及MySQL虚引用造成GC时间过长分析 | 京东云技术团队

京东科技开发者

MySQL G1 GC 企业号 6 月 PK 榜

BI分析能力:当今企业必备核心竞争力

夜雨微澜

HTML5 游戏开发实战 | 黑白棋

TiAmo

html html5 6 月 优质更文活动

直播系统源码知识分享:解你忧愁!降低直播延迟的实现

山东布谷科技

软件开发 源码搭建 直播系统源码 直播源码

重磅新品全球公测!华为云数据库又有大动作

平平无奇爱好科技

再见Navicat,dbeaver才是真香

程序员小毕

Java 数据库 程序员 后端 架构师

Redis跳跃表是如何添加元素的?

小小怪下士

Java redis 面试

【网络安全】堡垒机对于企业的重要性你知道吗?

行云管家

云计算 运维 网络安全 堡垒机

2023银川市等级保护测评中心地址在哪里?有几家?

行云管家

等保 等保测评 等级测评 银川

强化学习从基础到进阶-常见问题和面试必知必答[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 DDPG算法

瓴羊Quick BI四度入选魔力象限报告,标志着BI系统的国产化进程加速

对不起该用户已成仙‖

CSS中常用的颜色格式

南城FE

CSS css3 前端 设计

MaxCompute湖仓一体近实时增量处理技术架构揭秘

阿里云大数据AI技术

sql 大数据 分布式计算 数据处理 企业号 6 月 PK 榜

构建系列之新一代利器Esbuild(下)

江湖修行

前端 cli 构建 #web esbuild

【直播预告】HarmonyOS极客松赋能直播第三期:一次开发多端部署与ArkTS卡片开发

HarmonyOS开发者

HarmonyOS

Intellij IDEA 插件开发 | 京东云技术团队

京东科技开发者

Java IntelliJ IDEA 企业号 6 月 PK 榜 插件工程

华为云专家出品《从零到一•Python图像处理入门》电子书

华为云PaaS服务小智

Python 华为 华为云 华为开发者大会2023

程序员用哪一种IDE写代码比较好?

没有用户名丶

软件测试/测试开发丨Python内置库学习笔记

测试人

Python 软件测试 io 科学计算 内置库

STC89C52+AT24C02实现设备开机次数记录

DS小龙哥

6 月 优质更文活动

大语言模型的开发利器langchain

程序那些事

程序那些事 AIGC ChatGPT 大语言模型

Spring Boot配置文件加载顺序详解

2756

强化学习从基础到进阶--案例与实践[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 DDPG算法

强化学习从基础到进阶--案例与实践[7.1]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解项目实战

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 DDPG算法

一图讲清楚公众号扫码关注绑定手机号自动登录

越长大越悲伤

微信 公众号接入

SQL 优化(二):避免隐式转换

hungxy

爱奇艺App架构升级之路——64位适配探索与实践_硬件_爱奇艺技术产品团队_InfoQ精选文章