在 Android 6.0 上加载 protobuf-lite.so 时,如何修复 Android NDK 应用因 UnsatisfiedLinkError 崩溃?

How to fix Android NDK app crash with UnsatisfiedLinkError when loading protobuf-lite.so on Android 6.0?

我创建了一个 Android 应用程序,其中包含依赖于 Google 的 protobuf-lite 库的自定义 C++ 库。它在我最近尝试 运行 的所有设备上都运行良好(在 Android 7、8 和 8.1 下)。但是,我发现在旧设备 运行ning Android 6.0.1 或 6.0(华硕 Nexus 7 和一些旧的摩托罗拉 phone)上,应用程序在加载 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设备。

以下是我的配置的一些详细信息。

这是我的 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)

有没有人运行遇到过这个问题?任何有关如何解决此问题的提示都将不胜感激。

您需要更改正在使用的 NDK 版本。下面的文章建议迁移到 NDK 22 或更新版本将解决此问题。

unable to run on Android 6.0 after 7b77c0acedf708749b68304cc5f0ac469c9d7136

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

您的 protobuf 库是为 minSdkVersion 比您的应用程序的其余部分更高的而构建的,并且不能 运行 在您使用的设备上。