【问题标题】:I have an application, that uses the NDK, and it works perfect when I try to run it on some phones, but not on others我有一个使用 NDK 的应用程序,当我尝试在某些手机上运行它时,它运行良好,但在其他手机上却不行
【发布时间】:2017-06-28 12:32:31
【问题描述】:

我的应用可以在 Nexus 5、摩托罗拉 Moto G4 和电视盒性 Minix Neo-X9 上运行。 但是当我尝试在 LG G5 或 LeEco Le2 上运行它时,我遇到了以下问题:

06-28 14:24:14.869: E/AndroidRuntime(7264): FATAL EXCEPTION: main
06-28 14:24:14.869: E/AndroidRuntime(7264): Process: com.vidyo.vidyomod, PID: 7264
06-28 14:24:14.869: E/AndroidRuntime(7264): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.vidyo.vidyomod-1/base.apk"],nativeLibraryDirectories=[/data/app/com.vidyo.vidyomod-1/lib/arm64, /data/app/com.vidyo.vidyomod-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libVidyoClientApp.so"
06-28 14:24:14.869: E/AndroidRuntime(7264):     at java.lang.Runtime.loadLibrary(Runtime.java:367)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at java.lang.System.loadLibrary(System.java:1076)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at com.vidyo.VidyoClientLib.LmiAndroidAppJni.<clinit>(LmiAndroidAppJni.java:692)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at java.lang.Class.newInstance(Native Method)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.Instrumentation.newApplication(Instrumentation.java:1001)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.Instrumentation.newApplication(Instrumentation.java:986)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.LoadedApk.makeApplication(LoadedApk.java:582)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5116)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.ActivityThread.-wrap2(ActivityThread.java)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1628)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.os.Handler.dispatchMessage(Handler.java:111)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.os.Looper.loop(Looper.java:207)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at android.app.ActivityThread.main(ActivityThread.java:5917)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at java.lang.reflect.Method.invoke(Native Method)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
06-28 14:24:14.869: E/AndroidRuntime(7264):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)

代码是一样的,怎么在手机上能用,在别的手机上不能用? 我的意思是,它在某些方面完美运行库,而在其他方面则不然。我测试过,例如乐视是 6.00,而 Nexus 5 是 6.0.1。所以我认为这不是 Android 操作系统的问题

在我的 jniLibs 文件夹中,我有这个: jniLibs->armeabi-v7a->libVidyoClientApp.so

我是否还需要一个文件夹,例如:jniLibs->arm64-v8a -> libVidyoClientApp.so 或类似的东西? 因为这条线而问:

/data/app/com.vidyo.vidyomod-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libVidyoClientApp.so"

在我的 build.gradle 我有这个:

sourceSets.main {
    jni.srcDirs = []
    jniLibs.srcDir 'src/main/libs'
}

【问题讨论】:

  • 什么是libVidyoClientApp.so
  • 这是一个本地库文件,我已将其包含在我的库文件中。
  • 我在度假,在它工作之前,我一个接一个地检查了我的同事所做的提交,我发现了这个问题。检查我的回复

标签: android android-ndk dalvik renderscript unsatisfiedlinkerror


【解决方案1】:

对于 64 位设备(大多数现代手机和平板电脑),您应该提供 lib/arm64-v8a 中的所有库,或者不提供。如果没有 64 位库,系统将愉快地使用来自 lib/armeabi-v7a 的 32 位版本。但是,即使有一个 64 位库(通常来自某些 3rd 方 SDK),您的应用也会因 UnsatisfiedLinkError 而崩溃。

控制这种情况的最简单方法是为 ndb-build 设置 APP_ABI=armeabi-v7ausually in Application.mk file

使用 Android Studio (不是你的情况,jni.srcDirs = [] 禁用 NDK 集成),gradle 会覆盖它。你需要abiFilters in android.defaultConfig.ndk block 或者这样:

android {
  defaultConfig {
    externalNativeBuild {
      cmake {
        abiFilters "armeabi-v7a"
      }
    }
  }
}

或者,您可以将所有库编译为 64 位。对于一些繁重的计算任务,您可以毫不费力地获得显着的性能提升。在其他情况下,收益很小,但将 C++ 代码移植到 64 位可能是一项具有挑战性的工作。此外,这可能会显着增加 APK 的大小。如果您选择同时提供 32 位和 64 位版本的应用,建议发送至split the APK

特别是对于渲染脚本,性能提升可能不会超过处理多个 ABI 的麻烦。请注意,即使您将目标 API 设置为低于 21,gradle 也会复制 64 位 RenderScript 库。

【讨论】:

    【解决方案2】:

    显然问题是由同事添加的库引起的:

    compile 'com.github.mmin18:realtimeblurview:1.1.0'
    

    这个库在android defaultConfig中也需要这个:

        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
    

    这导致库由于某种原因无法在某些手机上运行

    【讨论】:

    • 诀窍在于,在 64 位设备上,您应该提供 lib/arm64-v8a 中的所有库,或者不提供。如果没有 64 位库,系统将愉快地使用 lib/armeabi-v7a 中的 32 位版本。但是,即使有一个 64 位库(通常来自某些 3rd 方 SDK),您的应用程序也会因 UnsatisfiedLinkError 而崩溃。
    • @AlexCohn:应该将其发布为答案,因为这是真正的问题
    • 是的,对此做出回答,我会接受它,因为它更好地解释了我的应用程序中发生的事情
    猜你喜欢
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 2019-11-22
    相关资源
    最近更新 更多