Android NDK 之CPU架构兼容与包体积控制方案
一、不同CPU架构之间的兼容性
Android 设备上不同CPU的架构兼容性如下图所示:
但是需要指出的是,以兼容模式运行会存在一些问题:
- 兼容模式运行的Native库无法获得最优性能。
- 兼容模式下运行会出现一些难以排查的内存问题。
- 系统会优先加载对应架构目录下的so库,当so库不全时,会导致一些Crash问题。
二、CPU架构兼容与包体积控制方案
1. 使用兼容模式的库
一般情况下,当我们确认Native库运行时为“性能不敏感”且“无运行时异常”的时候,建议使用兼容模式提供Native库,能有效降低Apk包的体积。
lib库结构如下:
另外,我们可以在上述基础上,做Native库的动态加载。将部分占体积较大的so库,存放在CDN上,在使用的时候进行动态加载Native库。
这块的方案思路有点类似 TBS 的动态内核加载,在加载完成之前,使用原生的WebView。
2. 构建时进行分包
目前应用市场支持根据当前设备的CPU架构进行同一应用不同CPU架构的分包下发。
那么我们在打包的时候,如何进行配置,可以参考以下:
splits {
abi {
enable true
reset()
include 'arm64-v8a','armeabi-v7a'
// exclude 'armeabi'
universalApk true
}
}
这里的参数我们都一一说明一下:
- enable: 是否启用ABI拆分机制
- reset():重置ABI列表为只空字符串,一半和include、exclude一起使用,如果要用必须在include和exclude前面
- include:指明要包含哪些ABI,目前使用最多的伪64位处理器的arm64-v8a,其次才是armeabi-v7a
- exclude:默认包含下所有ABI,可以移除一些ABI
- universalApk:是否打包一个通用版本,包含所有的ABI,默认值为 false
补充:构建时分包方案,不仅仅可以通过cpu架构进行区分,也可以根据分辨率等其他条件进行分包。
splits {
density {
enable true
exclude "ldpi", "tvdpi", "xxxhdpi"
compatibleScreens 'small', 'normal', 'large', 'xlarge'
}
}