Как добавить готовые библиотеки *.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
Другие вопросы по тегам