flutter android So库对齐
so 库说明
so 库在 android 中,是使用 c/c++代码编译出来的库文件,可以使用 ndk 调用,就是你在 android 代码中见到的 native 方法,具体的实现就在 so 库中
关于 so 库兼容性问题
andorid 中或多或少都会引用到第三方库,而很多第三方库中都有 so 的存在,不论是复制到项目中(如百度地图),或是 gradle 依赖(如个推) 其中都涉及到了 so 库的相关问题,如果你选择的库是有所有 cpu 类型可选还好,如果不是,那么就需要自定义设置了
举个栗子
你的 app 依赖两个库,分别是 lib1,lib2
lib1: arm64-v8a,armeabi-v7a
lib2: armeabi-v7a
那么当你运行在 v7 的手机上时,因为你的项目含有 v7 的 so 库,所以没有问题,可以跑起来
如果,你运行在 v8 手机上,那么你的项目就会 boom,崩了, 为啥呢? 这就涉及到 so 对齐了
so 对齐
简单来说,就是要有就必须都有,如果一个没有,那就一个都不要
比如上面的例子,如果你是自己复制到项目下的,你需要删掉 arm64-v8a 的文件夹
如果是个推那种使用 gradle 依赖的方案,那么你需要修改 gradle 文件,这个是我的个推的配置 gradle
// 个推的ndk配置
apply plugin: 'com.android.application'
android {
defaultConfig {
ndk {
abiFilters "armeabi-v7a"
// abiFilters "armeabi-v7a","arm64-v8a"
}
}
buildTypes {
debug {
ndk {
abiFilters "armeabi-v7a", "x86"
// abiFilters "armeabi-v7a", "x86"/*, "arm64-v8a"*/
}
}
release{
ndk{
abiFilters "armeabi-v7a"
}
}
}
}
repositories {
maven { url "http://mvn.gt.igexin.com/nexus/content/repositories/releases/" }
}
这里因为涉及到 flutter 的调试,而很多模拟器都是 x86 的,所以 debug 的情况下开启了 x86
最优选择
原则上来讲,so 库的最优选择是提供所有的 so,或者分 cpu 类型打包,这样能做到最优,因为 v8 读取 v7 的 so 库会有性能上的损失
如果全打包到 apk 里,则会增加 apk 体积
无奈,目前还没有提供多 cpu 分 apk 上传的应用商店,然后根据手机的 cpu 类型提供对应的下载
所以目前的方案是提供最低的 cpu 类型, 因为 v7 会去自动兼容 armeabi 的 而 v8 会兼容 v7 和 armeabi
比如只提供 armeabi so 的,你可以兼容 3 种 cpu 的手机,而只提供 v7 的就要少一点
目前 android 普遍应该都是 v7+的了,而 flutter 提供的 so 也只有 v7 和 v8 两种而已,所以我们基于这种情况,建议打包的时候自主删除除 armeabi-v7a 以外的选项
使用如上的 gradle 能解决大部分问题,可以在 gradle 中再修改下打包脚本,自动去除 lib 中的其他 cpu 类型
这部分可以参考美团的 flutter 原理与实践 SO 库兼容性部分 来尝试修改自己的 gradle 打包脚本