Как добавить готовые библиотеки *.so в андроид студию?
Я пытаюсь интегрировать Hyperledger Indy SDK. Однако при запуске моего кода я получаю ошибку
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: dlopen failed: library "libgnustl_shared.so" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
at java.lang.System.loadLibrary(System.java:1657)
Я пытаюсь следовать документации, представленной в репозитории проекта. Я попытался использовать пример проекта в этом блоге.
- Я смог собрать библиотеки *.so под виртуальной машиной Linux, скопировал встроенные файлы в мой проект Android Studio на Windows.
- Я добавил файлы в jniLibs forlder моего проекта для каждой архитектуры.
- Добавлен код для загрузки библиотеки внутри моей mainActivity
static{
System.loadLibrary("indy");
}
- Попытка создания файла CMake
cmake_minimum_required(VERSION 3.4.1)
add_library(indy SHARED IMPORTED)
include_directories(src/main/jniLibs/${ANDROID_ABI}/include)
Мой файл Gradle включает в себя:
android{
defaultconfig{
...
ndk{
moduleName "indy"
abiFilters 'armeabi-v7a'
}
}
...
sourceSets {
main {
jniLibs.srcDir 'src/main/jniLibs'
}
}
externalNativeBuild {
cmake {
path file('../CMakeLists.txt')
}
}
}
Тем не менее, продолжаю получать ту же ошибку при запуске приложения. Я знаю, что bash-скрипт, который собирает библиотеки на linux, использует инструменты android-ndk-r16b-linux-x86_64, поэтому я попытался понизить ndk в android studio, чтобы использовать ту же версию, но безуспешно.
Выходные данные сценария сборки
include/
indy_anoncreds.h
indy_core.h
...
lib/
libindy.a
libindy.so
libindy_shared.so
Как я могу использовать эти библиотеки в своем проекте Android Studio?
1 ответ
Проблема в основном связана с природой библиотек. Библиотеки динамичны в Android и должны быть связаны во время выполнения.
libindy.so
зависит от stl, openssl, libsodium и libzmq. Ты найдешь libgnustl_shared.so
в ндк. Все остальные необходимые готовые библиотеки также доступны здесь.
Что вам нужно сделать, это убедиться, что эти библиотеки присутствуют в папке jniLibs, и загружать их в библиотеки по порядку перед libindy.
System.loadLibrary("libgnustl_shared");
.
.
System.loadLibrary("indy");
Альтернативный подход:
В Indy есть подпроект, в котором мы используем libindy в качестве зависимости, и мы пытаемся создать одну динамическую библиотеку, которая имеет все зависимости. Ссылка на сайт
Если вы выполняете шаги, подобные vcx, вам не нужно иметь все библиотеки-ответчики в jniLibs, так как они уже будут частью окончательного файла.so
Это команда, которая делает одну толстую динамическую библиотеку со всеми символами и зависимостями, это (из ссылки, вставленной выше)
${LIBVCX}/target/${CROSS_COMPILE}/release/libvcx.a \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/libz.so \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/libm.a \
${TOOLCHAIN_DIR}/sysroot/usr/${NDK_LIB_DIR}/liblog.so \
${LIBINDY_DIR}/libindy.a \
${TOOLCHAIN_DIR}/${CROSS_COMPILE_DIR}/${NDK_LIB_DIR}/libgnustl_shared.so \
${OPENSSL_DIR}/lib/libssl.a \
${OPENSSL_DIR}/lib/libcrypto.a \
${SODIUM_LIB_DIR}/libsodium.a \
${LIBZMQ_LIB_DIR}/libzmq.a \
${TOOLCHAIN_DIR}/${CROSS_COMPILE_DIR}/${NDK_LIB_DIR}/libgnustl_shared.so -Wl,--no-whole-archive -z muldefs