美文网首页Gradle专题技术文移动开发
使用第三方库出现找不到so库UnsatisfiedLinkErr

使用第三方库出现找不到so库UnsatisfiedLinkErr

作者: f53bcbbc7c3e | 来源:发表于2016-08-26 17:34 被阅读33531次

首先这边引用环信SDK工程师总结的出现这个问题的一些原因(稍作排版修改):
引用 / 环信SDK工程师分析 UnsatisfiedLinkError

前言

在开发项目的时候我们免不了使用一些第三方的库来进行快速开发,有些第三方库只是简单的一个jar包,但是有些使用了jni开发,因此会包含so库文件,这个时候如果不消息我们就会遇到一个错误:java.lang.UnsatisfiedLinkError

最近经常遇到有开发者在问使用环信sdk的时候出现这个错误;这里分享下问题原因以及解决方案;

相关信息

这里需要先解释一下相关信息
hyphenatechatsdk提供的指令集类型仅提供armeabi-v7aarm64-v8ax86三种;
armeabiarmeabi-v7a是相近似的指令集,v7a是增强型指令集,运行速度,效率均有所提高,他们都是32位指令,并且兼容;arm64-v8a对应arm64位指令集;
arm64位策略和intel IA32不一样:intel64位指令是兼容intel32位指令,intel32位指令编译的程序可以直接在intel64位机器上运行;但是arm不是,arm64位和arm32位是彼此独立的指令系统,不兼容;arm这样设计的原因是因为运行在嵌入式上,设计指标更趋向于效率,和耗电考量;实际上arm64位芯片上同时包含着arm64指令处理器和arm32位指令处理器,只不过两个处理器彼此独立;

导致产生UnsatisfiedLinkError的几个原因

影响链接的限制条件: armeabi实际上可以运行在arm64位机器上,只不过Google增加了限制条件:

  1. Android4.x只要能找到so,就可以运行,so可以在armeabiarmeabi-v7aarm64-v8aso位置可以很随意;

  2. Android5.x开始,检查更加严格,会只有和芯片型号对应目录的so会安装到手机中;

举个例子:
开发环境下目录结构如下
libs/armeabi:libhyphenate.so libhyphenate_av.so
libs/armeabi-v7a:libmediadata.so
手机对应的指令集是armeabi-v7a,然后安装到手机的只有libmediadata.so

  1. Android6.x下,检查更加严格,有一条规则,之前测试有遇到,现在不太确认;
    libs/armeabi/: libhyphenate.so libhyphenate_av.so
    libs/arm64-v8a(没有此目录)
    arm64位机器上也可以运行,但是作为开发者通常会依赖其他开发包,比如baiduMap,也会用其他so,不能让所有开发者都删掉libs/arm64-v8a的目录;不过开发者可以尝试下删除arm64-v8a,只留armeabi,这样安装包会很小,在各个平台上也能运行;
    Google考量点是执行速率,更流畅的用户体验,作为开发者,服务提供者,我们希望apk尽可能小,对执行速度要求不高;

  2. armeabiarmeabi-v7a可以互换,现在市面上的手机很少有armeabi的,基本上是armeabi-v7aarm64位的高端机器。

  3. 查看手机芯片型号:cat /proc/cpuinfo, 仔细看一下打印信息,能够看明白手机指令集,是32位还是64位。

  4. x86目录,通常对应虚拟机,很多开发者喜欢在genymotion上开发调试,这个就对应86x86和前面说的intel IA32是一回事,所以只提供32位的,也能在x86-64位机器上运行;

  5. 我们的so还依赖于libsqlite.so,不过由于这个包从来没有变化,使用的是系统默认提供的/system/lib,在Android 6.x及以下的平台可以运行,Android7.x执行更严格的安全检查,禁止使用系统目录的内容,所以如果希望在Android7.x以上版本,需要把系统目录的libsqlite.so拷贝出来,也放在自己app对应指令目录下,由于目前Android7.x市面上没有机型,所以目前不在考虑范围;

  6. mips指令集的手机很少见,听说联想有出过,没见过;

  7. libs/armeabi/libhyphenate.solibs.without.audio/armeabi/libhyphenate.so是不同,libs/armeabi/libhyphenate.so会依赖于libs/armeabi/libhyphenate_av.so,如果找不到会报java.lang.UnsatisfiedLinkError

  8. 还有一个比较容易忽略的一点,现在我们的的项目一般都是引入好多个第三方库,第六点也提到了使用baiduMap这点,就是当一个项目引入多个库,不同的库有不同的so文件夹,当其中一个支持的比较少,但是另一个比较全时,也会出现这样的错误,解决方法就是不支持的so文件夹删除

举个例子:
环信支持的指令集arm64-v8aarmeabi-v7ax86
百度地图支持的指令集arm64-v8aarmeabiarmeabi-v7ax86x86_64mipsmips64
如果想在所有设备上都能运行,需要把x86_64mipsmips64这些删除;
根据前边所说可以保留armeabiarmeabi-v7a文件夹,然后复制armeabi-v7a里的so文件到armeabi就行了

结语

所以如果大家再遇到这样的问题,可以先根据以上信息排查下,无非就是某个库的 so 文件放多了,或者某个 so 库的文件放少了,或者是 jar 包和 so 不匹配了,这些只要细心看下 ide 的日志提示,很容易就解决,希望此篇文章能帮大家解决问题,谢谢!

文笔有限,如果问题,欢迎指正 _~

相关文章

网友评论

  • f886718d8e26:楼主你好 这个报错是为什么呢? 谢谢
    java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/com.wondersgroup.ggfuwuApp-1/lib/arm/libdetectFaceYSQ.so" has unexpected e_machine: 3
  • 7d6eb96d5e7e:楼主请教你一个问题,我使用的是UC的内核。他们内核的so文件只支持32bit手机。 而且这写so文件都是他们自己管理在一个动态下载的zip里面。 也就是说我本地不libs不需要添加任何so。 然后我64bit手机运行就报错加载无法加载32位的bit。我看了许多和你类似的文章,添加armeabi 文件,都没有解决我的问题。 还有一个办法就是修改应用默认bit,只加载32bit,但是不知如何实现。
    7d6eb96d5e7e:@穿裤衩闯天下 首先得谢谢您的回复。 您说的这个办法我试过了,但是最后还是无法加载64bit的so。
    f53bcbbc7c3e:首先我不知道你说的这个他们自己动态下载 zip 的压缩包处理 so 是怎么做的,但是android 引用最终打包到 apk 的 so 应该都是放在对应目录下,然后在安装时拷贝对应的 so 到系统的目录,先不管他们怎么处理 so;
    按照正常的逻辑,自己处理 so 需要指定 so 的位置,然后打包时可以设置包含哪些平台的 so,
    可以在你的 build.gradle 下加上一下配置试下 下边的armeabi-v7a 可以改成 armeabi
    android {
    compileSdkVersion 26
    defaultConfig {
    ...
    ndk {
    abiFilters 'armeabi-v7a'
    }
    }
    }
  • 963a34522567:大哥, 现在 更新到7.1 了, 这个是不是得更新下了, 在6.0 的时候看你的 这个文章很有用,
    f53bcbbc7c3e:这个在8.x 上适配应该也是没有问题的,因为我的 nexus 5x 就是8.1的系统,你会所的7.1系统不是是指哪方面呢?说出来大家讨论下
  • 裂缝中的阳光_c620:环信3.3.6 用的av下的,一直报这个,试了所有的方法 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/base.apk", zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.wisetrust.kylinfinance.mob.bank-2/split_lib_slice_4_apk.apk", zip file /vendor/lib64, /system/lib64]]] couldn't find "libhyphenate.so"
    f53bcbbc7c3e:看看你 arm64下 是否放了环信的 so
  • 495534effe58:java.lang.UnsatisfiedLinkError
    dlopen failed: "/data/app/com.google.android.webview-2/lib/arm/libwebviewchromium.so" is 32-bit instead of 64-bit
    这个问题有遇到过吗?
    f53bcbbc7c3e:这个是你把 so 放置错误导致,检查下应该是将 armeabi 的 so 放置在了 v8a 下
  • 明风桦:我的包都写了还是出现同样的错误,
    dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.hiapad.chattingservice-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.hiapad.chattingservice-1/lib/arm64, /data/app/com.example.hiapad.chattingservice-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libeasemob_jni.so"
  • b8189c3559f9:想问一下,用第三方的库,没有出错,可是自己要生成的库文件就报错,找不到库文件,也编译不出来库文件。自己写的demo网络下载文件,引用了"armeabi", "armeabi-v7a", "x86",三个库文件,全部存放于libs里边,也在build.gradle里边配置过了,下面贴出代码。
    public class TestJNI {
    static {
    System.loadLibrary("curl");
    System.loadLibrary("curlTest");
    }

    public static native void Init();
    public static native void Cleanup();
    public static native void TestDownload();
    public static native void TestHttpPost();

    }
    其中需要用到两个库

    java.lang.UnsatisfiedLinkError: Couldn't load curlTest from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.llcy.testjni-3.apk,libraryPath=/data/app-lib/com.llcy.testjni-3]: findLibrary returned null

    at java.lang.Runtime.loadLibrary(Runtime.java:358)
    at java.lang.System.loadLibrary(System.java:526)
    at com.llcy.testjni.TestJNI.<clinit>(TestJNI.java:10)
    at com.llcy.testjni.MainActivity.onCreate(MainActivity.java:17)
    at android.app.Activity.performCreate(Activity.java)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java)
    at android.app.ActivityThread.access$800(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java)
    at android.os.Handler.dispatchMessage(Handler.java)
    at android.os.Looper.loop(Looper.java)
    b8189c3559f9:ndk的版本应该是最新的Android NDK, Revision 15c (July 2017)
  • 2ded70ff228f:成功解决了导入环信的坑,和环信配种成功
  • 55f410a01e3f:求解,急!!云测后发现,多报错在android5.0以下的手机才会找不到这个so。
    AndroidRuntime FATAL EXCEPTION: main
    E AndroidRuntime Process: com.mengu.all, PID: 13354
    E AndroidRuntime java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "signal" referenced by "libcocos2dlua.so"...
    E AndroidRuntime at java.lang.Runtime.loadLibrary(Runtime.java:364)
    E AndroidRuntime at java.lang.System.loadLibrary(System.java:533)
    E AndroidRuntime at org.cocos2dx.lib.Cocos2dxActivity.onLoadNativeLibraries(Cocos2dxActivity.java:248)
    E AndroidRuntime at org.cocos2dx.lib.Cocos2dxActivity.onCreate(Cocos2dxActivity.java:263)
    E AndroidRuntime at org.cocos2dx.lua.AppActivity.onCreate(AppActivity.java:97)
    E AndroidRuntime at android.app.Activity.performCreate(Activity.java:5312)
    E AndroidRuntime at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
    E AndroidRuntime at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2552)
    E AndroidRuntime at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
    E AndroidRuntime at android.app.ActivityThread.access$800(ActivityThread.java:156)
    E AndroidRuntime at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
    E AndroidRuntime at android.os.Handler.dispatchMessage(Handler.java:102)
    E AndroidRuntime at android.os.Looper.loop(Looper.java:157)
    E AndroidRuntime at android.app.ActivityThread.main(ActivityThread.java:5872)
    E AndroidRuntime at java.lang.reflect.Method.invokeNative(Native Method)
    E AndroidRuntime at java.lang.reflect.Method.invoke(Method.java:515)
    E AndroidRuntime at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    E AndroidRuntime at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
    E AndroidRuntime at dalvik.system.NativeStart.main(Native Method)
  • dc6a097a25c4: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.hyphenate.chatuidemo-2/base.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.hyphenate.chatuidemo-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.hyphenate.chatuidemo-2/lib/arm, /data/app/com.hyphenate.chatuidemo-2/base.apk!/lib/armeabi-v7a, /data/app/com.hyphenate.chatuidemo-2/split_lib_dependencies_apk.apk!/lib/armeabi-v7a, /data/app/com.hyphenate.chatuidemo-2/split_lib_slice_0_apk.apk!/lib/armeabi-v7a, /data/app/com.hyphenate.chatuidemo-2/split_lib_slice_1_apk.apk!/lib/armeabi-v7a, /data/app/com.hyphenate.chatuidemo-2/split_lib_slice_2_apk.apk!/lib/armeabi-v7a, /data/app/com.hyphenate.chatuidemo-2/split_lib_slice_3_apk.apk!/lib/armeabi-v7a, /data/app/com.hyphenate.chatuidemo- ...
  • 707ff47fb492:No implementation found for void io.vov.vitamio.MediaPlayer.native_init()
    楼主这个问题对于mate9还有三星的好像s7(7.0系统)报错,其他低版本机器都没问题,有没有好的建议
    f53bcbbc7c3e:你这个应该也是底层的 so 库没加载上导致的,可以看下你这两款设备是什么平台的的 cpu,然后看看 vitamio 有没有针对他们的平台的 so,然后根据文章的描述看看排查下
  • tomato_wl:楼主我的问题是这样的,我这个是将工程作为库添加依赖之后才出现的,那个工程本身运行没有问题,添加依赖之后出现EXCEPTION, please implement com.mogujie.tt.imservice.network.MsgServerHandler.exceptionCaught() for proper handling.
    java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/cn.uartist.ipad-1/base.apk"],nativeLibraryDirectories=[/data/app/cn.uartist.ipad-1/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libsecurity.so"
    f53bcbbc7c3e:看你这个错误是 arm64-v8a 的库引用有问题,是不是你有引用多个 module,其中一些有 arm64-v8a,但是其中一些没有,这些都检查一下
  • 马拉松Mara:在jdk下使用64位的,读取32位编译的.dll文件,也会出现这个问题
    f53bcbbc7c3e:应该都一样的,只是 pc 平台限制应该更严格一些,移动端的如果找不到64为可以使用32位的兼容,
  • 6ca4c2a30257:编译时找不到方法,求指教UnsatisfiedLinkError: Native method not found
    f53bcbbc7c3e:看看你完整的错误提示是什么
  • 346d2f2f2dc5:楼主你好,请教我这个问题是什么原因!
    java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad in "/data/app/com.zuxia.edu.zuxiaclassroom-4/lib/x86/libijksdl.so"
    at java.lang.Runtime.loadLibrary(Runtime.java:372)
    at java.lang.System.loadLibrary(System.java:1076)
    at tv.danmaku.ijk.media.player.IjkMediaPlayer$1.loadLibrary(IjkMediaPlayer.java:175)
    at tv.danmaku.ijk.media.player.IjkMediaPlayer.loadLibrariesOnce(IjkMediaPlayer.java:187)
    at tv.danmaku.ijk.media.player.IjkMediaPlayer.initPlayer(IjkMediaPlayer.java:228)
    at tv.danmaku.ijk.media.player.IjkMediaPlayer.<init>(IjkMediaPlayer.java:224)
    at tv.danmaku.ijk.media.player.IjkMediaPlayer.<init>(IjkMediaPlayer.java:215)
    f53bcbbc7c3e:看你这个 loadLibrary 是IjkMediaPlayer此类触发的,可以检查下这里边的 static 对应的 so 名称是否正确,
    346d2f2f2dc5:@穿裤衩闯天下 我在真机上面也跑了,但是还是出现了这个问题,我不是做jni的,x86的so文件是有的
    f53bcbbc7c3e:看你这个应该是在模拟器上运行的,而且应该是你自己你的 jni 开发的吧,是否有编译 x86 平台的 so 呢?
  • b1f5f972d37d:并没有armeabi
    f53bcbbc7c3e:新版 sdk 只保留了 armeabi-v7a,和 armeabi 通用
  • 刘擎昊:请教一下,我的这个错误您的解决方案适用么?谢谢
    java.lang.UnsatisfiedLinkError: Couldn't load sec from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.hhearth.android-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.hhearth.android-2, /vendor/lib, /system/lib]]]: findLibrary returned null
    at java.lang.Runtime.loadLibrary(Runtime.java:358)
    at java.lang.System.loadLibrary(System.java:526)
    at com.uzmap.pkg.uzcore.external.Enslecb.<clinit>(Enslecb.java:20)
    at com.uzmap.pkg.uzcore.external.g.b(NativeWrapper.java:149)
    at com.uzmap.pkg.uzcore.d.a(InternalDelegate.java:101)
    at com.uzmap.pkg.uzapp.UZApplication.onCreate(UZApplication.java:22)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
    at ...
    刘擎昊:@穿裤衩闯天下 我现在还是用同样的设备扫描下载的app安装,点击崩溃报错误,如果是armeabi跟armeabi-v7a冲突或者找不到的话,我删除其中之一还是报同样的错误。我现在把所有的jnilib包都放到了Libs里面。然后在build.gradle中加入: sourceSets{
    main{
    jniLibs.srcDirs = ['libs']
    }
    }
    还是会报同样的错误。看来是少导入包了?还是文件路径不对找不到.so文件?
    f53bcbbc7c3e:这个错误就是找不到对应的 so,不是很清楚这个 apiCloud 的逻辑,不知道你这个在云编译时是否安装到了不同的设备,可以确认下你的 so 库这些是否更新到了你的 apiCloud,或者你这个在云端打包的结果是不是在所有设备都有上边的错误,根据这个排查下
    刘擎昊:目前是本地测试android studio打包没有任何问题(可能机型的问题),上传apicloud云编译之后点击崩溃报这个错误。卡在这了,搜不到实质性的进展帖子,于是看到楼主的简书
  • 1c468809c701:第一次在简书留言,留给楼主,楼主写得好,就想起雁过留声。必须给个赞!
    f53bcbbc7c3e:谢谢,希望能帮到你:smile:
  • d09de5f94888:可以的,解决了问题:+1:
    f53bcbbc7c3e:@cloud_枫叶 解决就好:smile:
  • 96f13387a342:Google Nexus 6 升到7.0了~ :wink:
    f53bcbbc7c3e:恩,已经给自己的5x 升级到7.1.1:relaxed:
  • ac7b844056a2:厉害呢 我的 哥
  • e3c48ed7e6da:如果程序安装过程中so丢失怎么办?
    f53bcbbc7c3e:这个还一般没有遇到过,猜测有可能是 apk 中的 so 和设备 cpu 不匹配吧,或者可以多尝试几次试试
  • 满脸胡渣的年轻大叔:这个知识点不错。。。。 点个赞。。。

本文标题:使用第三方库出现找不到so库UnsatisfiedLinkErr

本文链接:https://www.haomeiwen.com/subject/vsdzsttx.html