包体积优化-其他
包体积优化 - 其他
so 优化
只编译指定平台的 so
一般我们都是给 arm 平台的机器开发,如果没有特殊情况,我们一般只需要考虑 arm 平台的。具体的方法是 app 下的 build. gradle 添加如下代码:只保留 armeabi(前几年)
或者 armeabi-v7a(目前)
1
2
3
4
5
6
7
android {
defaultConfig {
ndk {
abiFilter "armeabi"
}
}
}
各个平台的差别如下:
平台 | 说明 |
---|---|
armeabi-v 7 a | arm 第 7 代及以上的处理器,2011 年后的设备基本都是 |
arm 64-v 8 a | arm 第 8 代 64 位处理器设备 |
armeabi | arm 第 5、6 代处理器,早期的机器都是这个平台 |
x 86 | x 86 32 位平台,平板和模拟器用的多 |
x 86_64 | x 86 64 位平台 |
通过 productFlavors
配置动态包:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
flavorDimensions "default"
productFlavors {
arm32 {
dimension "default"
ndk {
abiFilters "armeabi-v7a"
}
}
arm64 {
dimension "default"
ndk {
abiFilters "armeabi-v8a"
}
}
}
分架构打包
分架构打包能减少 libs 文件夹体积,libs 文件夹里会包含不同架构的 so 库集合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
splits {
// 基于不同的abi架构配置不同的apk
abi {
// 必须为true,打包才会为不同的abi生成不同的apk
enable true
// 默认情况下,包含了所有的ABI。
// 所以使用reset()清空所有的ABI,再使用include指定我们想要生成的架构armeabi-v7a、arm-v8a
reset()
// 逗号分隔列表的形式指定 Gradle 应针对哪些 ABI 生成 APK。只与 reset() 结合使用,以指定确切的 ABI 列表。
include "armeabi-v7a", "arm64-v8a"
// 是否生成通用的apk,也就是包含所有ABI的apk。如果设为 true,那么除了按 ABI 生成的 APK 之外,Gradle 还会生成一个通用 APK。
universalApk true
}
}
移除调试符号
- 自己编译的 so
release 包的 so 中移除调试符号。可以使用 Android NDK 中提供的 arm-eabi-strip
工具从原生库中移除不必要的调试符号
如果是 cmake 来编译的话,可以再编辑脚本添加如下代码:
1
2
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
- 别人编译的 so
联系 so 作者修改,一般很难联系到。
- 都下沉到 armeabi,代码判断使用指定的 so
对于项目当中使用到的视频模块的 So,它对性能要求非常高,所以我们采用了另外一种方式,我们将所有这个模块下的 So 都放到了 armeabi 这个目录下,然后在代码中做判断,如果是别的 CPU 架构,那我们就加载对应 CPU 架构的 So 文件即可。这样即减少了包体积,同时又达到了性能最佳。最后,通过实践可以看出 So 瘦身的效果一般是最好的。
so 压缩
分架构打包是减少 so 的数量,so 压缩是减少 so 的单个体积。
1
android:extractNativeLibs="true"
android:extractNativeLibs = true
时,gradle 打包时会对工程中的 so 库进行压缩,最终生成 apk 包的体积会减小。
但用户在手机端进行 apk 安装时,系统会对压缩后的 so 库进行解压,从而造成用户安装 apk 的时间变长。
so 动态下发
Google 官方
AAB (Android App Bundle)
Google Play 要求 2022 年 8 月份起新应用须打包为 AAB 格式,开发者上传打包文件整合成 aab 格式,根据不同的处理器/分辨率等下载对应的安装包,减少冗余,所以安装包会减小。
Android App Bundle 是一种发布格式,其中包含你应用所有经过编译的代码和资源,它将 APK 生成及签名交由 Google Play 来完成。
Google Play 就是基于对 aab 文件处理,将 App Bundle 在多个维度进行拆分,在 资源维度
,ABI 维度
和 Language 维度
进行了拆分,你只要按需组装你的 Apk 然后安装即可。如果你的手机是一个 x 86,xhdpi 的手机,你在 google play 应用市场下载 apk 时,gogle play 会获取手机的信息,然后根据 App Bundle 会帮你拼装好一个 apk,这个 apk 的资源只有 xhdpi 的,而且 so 库只有 x 86,其他无关的都会剔除。从而减少了 apk 的大小。
Dynamic Feature
Android App Bundle 动态化⽅案 Qigsaw
Qigsaw 是一套基于 Android App Bundles 实现的 Android 动态组件化方案,它无需应用重新安装即可动态分发插件。
资源后下发
比如 APP 中内置的一些资源,如 mp3、mp4 文件,图片等。
图片配合图片库,远程加载图片,可以预加载一些核心业务的图片资源,提升体验。
其他方案
业务裁剪
用户不多的业务裁剪
插件化
将部分功能用插件加载;Google Play 不能用插件化技术,审核不过,严重可能导致账号被封
混合开发
将经常动态变化,性能要求不高的页面改成混合开发。
裁剪三方库
- 如 support 库,只保留有用的部分
- WorkManager 库
- FCM 库等