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打包脚本