Общая библиотека в apk не найдена во время выполнения - PullRequest
0 голосов
/ 20 сентября 2018

Я занимаюсь разработкой для Android с использованием OpenSSL.

Я кросс-компилирую его для armeabi (32b), используя автономные наборы инструментов Android NDK.Я кросс-компилирую нативные библиотеки C, копирую файлы OpenSSL / native library .so внутри моей папки libs/, на которую ссылается мой gradle следующим образом:

sourceSets {
    main {
        jniLibs.srcDir(file("libs/"))
    }
}

В любом случае, конечный результатв том, что мой .apk выглядит следующим образом:

 - > classes.dex
 - > lib/
     -> armeabi/
        -> libcrypto.so
        -> libssl.so
        -> libmynativelibrary.so
 - > res/ (...)
 - > resources.arsc
 - > META-INF/ (...)
 - > kotlin/ (...)
 - > AndroidManifest.xml

Общие библиотеки - это правильные 32-битные файлы ARM ELF.Я использовал этот точный APK на устройстве уровня API 24 с большим успехом (Android 7.0 +).

Проблема: Когда я переключаюсь на устройство уровня 21 API (Android 5.1)-, я подозреваю, что у меня возникнет та же проблема с Android 6.0), программа мгновенно падает при загрузке libmynativelibrary.so.

Так как libcrypto.so является зависимостью libmynativelibrary.so, программа пытается загрузить ее,На самом деле он работает нормально на уровне API 24+, но падает на уровне API 23-.Это потому, что загруженная библиотека не в моей .apk, а в системе. И такие библиотеки, кажется, недоступны ниже уровня API 24.

Мой вопрос: Как явно указать Android искать библиотеку в .apkсначала файл вместо обычных каталогов системных библиотек?

Заранее спасибо.

1 Ответ

0 голосов
/ 20 сентября 2018

До Nogut системные библиотеки не были защищены от пользовательских приложений.Конфликты имен проблематичны, они заставили Google изобрести отдельное пространство имен для общей библиотеки времени выполнения C ++, которая является частью Android NDK.

Библиотеки OpenSSL также широко используются вне вашего контроля.Они могут быть загружены в ваш процесс даже до того, как у вас появится возможность загрузить свой собственный libssl.

Таким образом, наилучшим выбором будет сборка OpenSSL в виде статических библиотек и статическая привязка libmynativelibrary.so к нему.Таким образом, у вас есть монолитный двоичный файл, который не зависит от других.

Если вы не можете следовать этому курсу, вам следует создавать библиотеки OpenSSL с искаженными именами, например, libmyssl.so и libmycrypto.so.Это может помочь избежать простого конфликта имен с системными библиотеками.

Еще лучше, следуйте примеру NDK и предоставьте уникальное пространство имен для вашего SSL API.

Не ожидайте, что загрузкабиблиотеки явно из их распакованного местоположения в ApplicationInfo.nativeLibraryDir будут надежным решением: как я уже говорил, системные библиотеки могут загружаться в ваше адресное пространство раньше.

Обратите внимание, что перед Lollipop вы также вручную загрузите все несистемные зависимости и в правильном порядке.

Кроме того, новый NDK отбросил armeabi , поэтому рассмотрите возможность перехода на armeabi-v7a.

...