Я создал приложение 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)
Кто-нибудь сталкивался с этой проблемой раньше? Любая подсказка о том, как это исправить, будет принята с благодарностью.