Как исправить падение приложения Android NDK с помощью UnsatisfiedLinkError при загрузке protobuf-lite.so на Android 6.0? - PullRequest
1 голос
/ 01 апреля 2019

Я создал приложение Android с настраиваемой библиотекой C ++, которая зависит от библиотеки Protobuf-Lite от Google. Он прекрасно работает на всех последних устройствах, на которых я пытался его запустить (под Android 7, 8 и 8.1). Однако я обнаружил, что на старых устройствах под управлением Android 6.0.1 или 6.0 (Asus Nexus 7 и некоторые старые телефоны Motorola) происходит сбой приложения при загрузке зависимости libprotobuf-lite.so.

Вот трассировка стека, которую я получаю:

E/AndroidRuntime: FATAL EXCEPTION:
main Process: com.mycompany.core, PID: 11582 java.lang.UnsatisfiedLinkError:
dlopen failed: cannot locate symbol "__aeabi_memmove8" referenced by "/data/app/com.mycompany.core-2/lib/arm/libprotobuf-lite.so"...
at java.lang.Runtime.loadLibrary(Runtime.java:372)
at java.lang.System.loadLibrary(System.java:1076)
at com.mycompany.core.CameraTestActivity.<clinit>(CameraTestActivity.java:46)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2317)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)$
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Это действительно странно, потому что отсутствующий символ "__aeabi_memmove8", похоже, является функцией низкоуровневой стандартной библиотеки, и я не совсем понимаю, почему его не найти в Android 6.

Кроме того, я вполне уверен, что проблема связана с неправильным связыванием protobuf-lite, поскольку предыдущие версии моего приложения, в которых не использовался protobuf, нормально работали на этих устройствах Android 6.

Ниже приведены некоторые сведения о моей конфигурации.

  • Версия Protobuf: 3.6.1
  • Пакет Lib кросс-скомпилирован из исходного кода с использованием графического интерфейса Cmake, набора инструментов NDK r18 и MinGW
  • Приборы ABI: armeabi-v7a
  • Версия компиляции Android SDK: API 28
  • Набор инструментов для сборки приложений: Gradle + CMake.
  • Android Studio 3.1.3

Вот мой файл build.gradle:

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.mycompany.core"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            ndk{
                abiFilters "arm64-v8a", "armeabi-v7a"
            }
        }

        debug {
            ndk{
                abiFilters "arm64-v8a", "armeabi-v7a"
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation "android.arch.lifecycle:extensions:1.1.0"
    implementation "android.arch.lifecycle:viewmodel:1.1.0"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

А вот мой файл CMakeLists.txt:

cmake_minimum_required(VERSION 3.4.1)

include_directories(src/main/cpp/protobuf/include)

file(GLOB SRCS
    "src/main/cpp/core/*.cpp"
    )

file(GLOB JNI_SRCS
        "src/main/cpp/jni/*.cpp"
        )

add_library(mycorelib SHARED ${SRCS} ${JNI_SRCS})

find_library(log-lib log)

add_library(libprotobuf-lite SHARED IMPORTED)

set_target_properties(libprotobuf-lite
                    PROPERTIES IMPORTED_LOCATION
                    ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libprotobuf-lite.so)

target_link_libraries(mycorelib
                        android
                        jnigraphics
                        ${log-lib}
                        libprotobuf-lite)

Кто-нибудь сталкивался с этой проблемой раньше? Любая подсказка о том, как это исправить, будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Это https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md#cannot-locate-symbols.

Ваша библиотека protobuf была создана для более высокого minSdkVersion, чем остальная часть вашего приложения, и не может работать на устройстве, которое вы используете.

0 голосов
/ 01 апреля 2019

Вам необходимо изменить версию используемого NDK.Статья ниже предполагает, что переход на NDK 22 или более поздней версии исправит это.

невозможно запустить на Android 6.0 после 7b77c0acedf708749b68304cc5f0ac469c9d7136

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...