安卓集成第三方.so的一些常见异常
前言:众所周知,我们使用的第三方SDK基本上都是.so文件+上一个jar包。然而我们写代码的时候总会出现这样和那样的问题,现在我就在这里汇总一下。这里只能解决Android studio的,eclipse仅供参考eclipse you are drunk.
一.调用.so 文件时报错has text relocations
说明编译.so文件时使用了较高版本sdk
一般都出现在targetSdkVersion 23,虽然不明白原理但是6.0是so库的一个分水岭
解决方案(两种)
- 下载最新的SDK(jar和so)
- 继续使用你现在正在用的SDK,并在你的module的build.gradle中配置上:
android {
……
defaultConfig {
……
targetSdkVersion 22
}
}
正如上述所说的使用了较高版本sdk,所以如果是22就写21一直减到能正常build为止
二.常见的因为缺失对应CPU的.so而引发的问题:
- java.lang.UnsatisfiedLinkError:No implementation found forXXX方法名
- java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file /data/app/com.xxx.xxx-2/base.apk”],nativeLibraryDirectories=[/data/app/com.xxx.xxx-2/lib/arm64,/data/app/com.xxx.xxx-2/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn’t find “libxxx.so”
这里列出两种,当然可能会是x86等类型的找不到
导致问题的原因主要有两种:
- so文件与jar不匹配,或者缺失.so文件。
解决办法:
下载与.so相匹配的jar下载匹配的.so文件 - 由于在X86手机上运行,而此时高德地图官网并未发布X86的so文件,导致应用崩溃。
(注:android4.4之后的大部分机型都是X86的)
解决办法:
只保留armeabi文件夹,其他的统统删掉,因为大多数x86平台的手机都会兼容armeabi的版本。
但是会发现就算这样做了在模拟器上面依旧装不上,那是因为模拟器没有兼容,但是他可以替换平台。如果是genymotion的话,需要安装一个转换为arm的插件。
配置过后依然报以上错误的分析:
首先附上解决方案
请在你的module的build.gradle中配置上
android {
……
defaultConfig {
……
ndk {
……
abiFilters "armeabi"
}
}
}
当你build完了之后如果没有gradle.properties文件那么会报下面的错误
点击修复即可,Android studio会自动帮你创建gradle.properties文件
并在里面写上android.useDeprecatedNdk=true
这个配置的含义:编译APK时只保留jniLibs文件夹下面armeabi文件夹
解释:
因为很多关联的jar包和arr里面其实已经添加了arm64-v8a、armeabi、armeabi-v7a、mips、mips64、x86、x86_64其中的两个以上的文件夹,而我们只需要一个文件夹armeabi。上述已经解释过了,这里再解释一次,除了模拟器,真机都会兼容armeabi中的.so文件,但是只要你写了非armeabi的文件夹,Android build的时候就会认为你是做了.so的优化处理的,那么在不是armeabi CPU的手机上使用的时候,系统就会去找对应的文件夹下面的.so文件,当然会报错咯。
然而我们又不能帮助客户去手动删除armeabi以外的文件夹,所以就用gradle只保留armeabi。
三、System.loadLibrary(“xxx”)
相信有的人应该自己load过.so,依然有很多人load的时候报错,原因是名字写错了
.so文件的全名是libxxx.so
静态代码块中的代码就应该是
static {
System.loadLibrary("xxx");
}
注意如果你自己写C/C++库的话命名必须是libxxx.so格式的不能少了前缀lib
以上:
为了祭奠我因为这些bug浪费的时间