缘由:
由于项目需要,引用了不同平台的so文件,分别a.so, b.so ,其中a.so 只有armabi-v7a版本,b.so通过gradle配置自动下载,编译运行后程序启动,运行到需要使用a.so 的地方直接闪退;报错:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file xxxxxxxxxxxxxx
xx.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "xxx.so"
at java.lang.Runtime.loadLibrary(Runtime.java:367)
at java.lang.System.loadLibrary(System.java:1076)
分析原因:
从AS中build 一个apk出来 解压查看lib目录 发现里面带有除armabi-v7a目录外 还有其他目录,并且每个目录都有b.so,但是没有a.so文件,再看运行的android 设备 是支持arm64-v8a,根据Android 寻找so的机制,可以得到答案,该Android 设备启动时先到系统目录寻找,没找到,再到软件内部lib找,找到与它适配的目录 arm64-v8a ,继续到目录中寻找用到的a.so、b.so文件,然而除了armabi-v7a目录外其他目录都没有a.so文件,于是系统就抛出这个错误,直接闪退;
通过网上比较多的说法,Android Studio 在打包apk时 会自动把支持的所有so版本复制到apk的lib目录下,由于b.so带有各种版本的so文件 ,打包时把b.so的所有版本随同 arm64-v8a 、x86等目录一并复制到lib中,但是由于a.so 只有armabi-v7a 版本,最终导致其他目录不存在a.so ;
可以得出,这种错误会出现在支持armabi-v7a以外的其他cpu架构中;
解决问题
- 条件允许的情况下我们可以选择为a.so生成多个版本的文件,但是这样会导致apk文件增大很多;
- 在app下的build.gradle中添加如下配置:(推荐)
android {
...
ndk {
//只保留armeabi-v7a的目录,具体保留那个根据自己需求
abiFilters "armeabi-v7a"
}
}