安卓集成第三方.so的一些常见异常

安卓集成第三方.so的一些常见异常


前言:众所周知,我们使用的第三方SDK基本上都是.so文件+上一个jar包。然而我们写代码的时候总会出现这样和那样的问题,现在我就在这里汇总一下。这里只能解决Android studio的,eclipse仅供参考eclipse you are drunk.

一.调用.so 文件时报错has text relocations

说明编译.so文件时使用了较高版本sdk
一般都出现在targetSdkVersion 23,虽然不明白原理但是6.0是so库的一个分水岭

解决方案(两种)

  1. 下载最新的SDK(jar和so)
  2. 继续使用你现在正在用的SDK,并在你的module的build.gradle中配置上:
android {
    ……
    defaultConfig {
        ……
        targetSdkVersion 22
    }
}

正如上述所说的使用了较高版本sdk,所以如果是22就写21一直减到能正常build为止

二.常见的因为缺失对应CPU的.so而引发的问题:

  1. java.lang.UnsatisfiedLinkError:No implementation found forXXX方法名
  2. 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等类型的找不到

导致问题的原因主要有两种:

  1. so文件与jar不匹配,或者缺失.so文件。
    解决办法:
    下载与.so相匹配的jar下载匹配的.so文件
  2. 由于在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
静态代码块中的代码就应该是

扫描二维码关注公众号,回复: 2234664 查看本文章
    static {
        System.loadLibrary("xxx");
    }

注意如果你自己写C/C++库的话命名必须是libxxx.so格式的不能少了前缀lib
以上:
为了祭奠我因为这些bug浪费的时间

猜你喜欢

转载自blog.csdn.net/arios171/article/details/52538104