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