【问题标题】:Using JavaCV and Realm together causes "java.lang.UnsatisfiedLinkError"一起使用 JavaCV 和 Realm 会导致“java.lang.UnsatisfiedLinkError”
【发布时间】:2016-01-28 16:14:04
【问题描述】:

我最近尝试启动 JavaCV 的 FFmpegFrameGrabber 实例时遇到以下错误:

java.lang.UnsatisfiedLinkError: org.bytedeco.javacpp.avutil
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:324)
    at org.bytedeco.javacpp.Loader.load(Loader.java:413)
    at org.bytedeco.javacpp.Loader.load(Loader.java:381)
    at org.bytedeco.javacpp.avformat$AVFormatContext.<clinit>(avformat.java:2597)
    at org.bytedeco.javacv.FFmpegFrameGrabber.startUnsafe(FFmpegFrameGrabber.java:386)
    at org.bytedeco.javacv.FFmpegFrameGrabber.start(FFmpegFrameGrabber.java:380)...

虽然存在此问题的解决方案,但没有一个对我有用。

经过多次试验,我发现很奇怪,如果我的项目中不包含 Realm,我将不再收到此错误。

这是我的 build.gradle 文件的一部分,其中包含所有这些库:

compile group: 'org.bytedeco', name: 'javacv', version: '1.1'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: 'android-x86'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.8.1-1.1', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.8.1-1.1', classifier: 'android-x86'

// ORM
compile 'io.realm:realm-android:0.87.2' // Tested NOT OK - Causes JavaCV to crash
//

我在想这个问题可能有一个我不知道的解决方案。我在互联网上没有任何地方提到图书馆不兼容或为什么会发生这种行为。

我将使用任何人可能需要的任何其他详细信息来编辑这篇文章。

任何帮助将不胜感激。

编辑

我尝试应用here 中描述的修复程序。 现在我的包装选项如下所示:

packagingOptions {
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.properties'
    exclude 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.xml'
    exclude 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.properties'
    exclude 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.xml'

    exclude "lib/arm64-v8a/librealm-jni.so"
}

很遗憾,此更改无效。我还是卡住了。

【问题讨论】:

  • 我想知道这是否与 Realm 常见问题解答中提到的 32-bit 64-bit 原生库问题有关。
  • 如果您提到“无法加载”librealm-jni.so”,那么您可能遇到了一些问题。我将尝试常见问题解答中提供的解决方案并进行报告。
  • 这听起来很像@EpicPandaForce 提到的 32 位与 64 位问题:realm.io/docs/java/latest/#faq 请参阅“无法加载“librealm-jni.so””。 Realm 为 32 位和 64 位提供二进制文件,但如果其他库不这样做,Android 可能会加载错误的版本,从而使您的应用程序崩溃。常见问题解答中有解决方法
  • 我根据@EpicPandaForce 的建议更新了我的答案。然而它没有任何效果。我正在三星 Galaxy S4 和 Nexus 5X 上进行测试,据我所知,它们都是 32 位设备。
  • 嘿@ChristianMelchior,我已经尝试了常见问题解答中建议的修复,但错误仍然存​​在。我仔细检查过,5X 确实是 64 位的,但 Galaxy S4 不是,并且遇到了同样的问题。任何建议都会很有帮助

标签: java android realm javacv


【解决方案1】:

在我的一位同事的帮助下,我已经能够解决这个问题。

除了问题中描述的步骤之外,我们:

  • 复制 app/src/main/jniLibs/armeabiapp/src/main/jniLibs/armeabi-v7a 文件夹中的所有 .so 文件李>
  • 添加

    ndk { abiFilters "armeabi-v7a" }

    到模块 build.gradle 文件的 defaultConfig 部分

  • 添加

    lintOptions { 中止错误错误 }

    到模块 build.gradle 文件的 android 部分

如果可以的话,我会尽量向任何需要的人提供进一步的说明。

【讨论】:

    【解决方案2】:

    首先出现此问题是因为 Gradle 无法从 maven 配置文件中正确解析依赖项。在我的情况下,只有 x86 依赖项发送到 APK。这意味着上面的代码仅适用于 x86 cpu 架构。解决方案应该在 Android Studio 上完成。但作为解决方法,我这样做了:

    1. 下载二进制文件javacv-platform-1.3.1-bin.zip。来自:https://github.com/bytedeco/javacv
    2. 目录javacv-bin复制这些jar到新目录

      1. ffmpeg-android-arm.jar
      2. opencv-android-arm.jar
      3. ffmpeg-android-x86.jar
      4. opencv-android-x86.jar
    3. 对于 2.1 2.2 文件,解压缩这些 jar,然后转到 libarmeabi。然后将所有*.so文件复制到你的项目下:

      1. app/src/main/jniLibs/armeabi/
      2. app/src/main/jniLibs/armeabi-v7a/
    4. 您可以通过将依赖项复制到 app/src/main/jniLibs/x86/ 来对 2.3 * 2.4 jar 执行相同的操作。如果确实没有,请检查您的apk

    就是这样。

    【讨论】:

    • 我想 gradle 没有什么问题,javacv 只有两个架构(armeabi,x86),而例如opencv4android 有更多(armeabi、“armeabi-v7a、”x86、mips - 对于 opencv 3.* 的 x64 甚至更多)。因此,如果这些 .so 文件甚至不存在于互联网上,其他文件夹当然是空的
    • 这正是问题所在.. 如果您有一个用于任何 CPU 架构的目录。系统将仅在该目录中查找本机库。所以你需要从其他兼容的库中复制库或删除这个目录。明白了吗?
    猜你喜欢
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2019-12-11
    • 1970-01-01
    • 2023-03-04
    • 2010-11-04
    • 1970-01-01
    相关资源
    最近更新 更多