У меня есть приложение, которое использует NDK, и оно отлично работает, когда я пытаюсь запустить его на некоторых телефонах, но не на других

Мое приложение работает на Nexus 5, Motorola Moto G4 и телевизионной коробке Sex 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)

Код такой же, как он может работать на телефоне, а не работать на другом телефоне? Я имею в виду, что на некоторых библиотека работает идеально, а на других нет. И я протестировал, например, LeEco 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'
}

2 ответа

Решение

Для 64-разрядных устройств (большинство современных телефонов и планшетов) вы должны предоставить все библиотеки в lib/arm64-v8a или ни в одной из них. Если нет 64-битных библиотек, система с радостью будет использовать 32-битную версию из lib / armeabi-v7a. Но если есть хотя бы одна 64-битная библиотека (часто из какого-то стороннего SDK), ваше приложение завершится сUnsatisfiedLinkError.

Самый простой способ контролировать это - установитьAPP_ABI=armeabi-v7aдляndb-build, обычно в файлеApplication.mk.

С Android Studio (не ваш случай,jni.srcDirs = []отключает интеграцию NDK), gradle переопределяет это. Вам нужны abiFilters в блоке android.defaultConfig.ndk или вот так:

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

Кроме того, вы можете скомпилировать все ваши библиотеки для 64-битных. Для некоторых сложных вычислительных задач вы можете получить значительный прирост производительности без особых усилий. В других случаях выигрыш минимален, но портирование кода C++ на 64 бит может быть сложной задачей. Кроме того, это может значительно увеличить размер вашего APK. Если вы решите предоставить 32-битную и 64-битную версии своего приложения, рекомендуется разделить APK.

Специально для Render Script есть вероятность, что выигрыш в производительности не перевесит хлопот с несколькими ABI. Обратите внимание, что даже если вы установите целевой API ниже 21, Gradle скопирует 64-битные библиотеки RenderScript.

По-видимому, проблема была вызвана библиотекой, которую добавил coleague:

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

Эта библиотека также необходима в android defaultConfig this:

    renderscriptTargetApi 19
    renderscriptSupportModeEnabled true

И по какой-то причине библиотека не работала на некоторых телефонах

Другие вопросы по тегам