Как динамически загрузить скомпилированную нативную библиотеку в приложение Android? - PullRequest
1 голос
/ 08 мая 2019

Я пытаюсь динамически загрузить собственную библиотеку libhello_world.so в пример проекта Android. Моя цель - чтобы приложение работало нормально, а во время выполнения извлекало библиотеку и загружало ее, чтобы ее можно было использовать.
В настоящее время структура приложения для Android

├── AndroidManifest.xml
├── java
│   └── example
│       └── myapp
│           └── some
│               └── exampleapp
│                   ├── Computation.java
│                   └── MainActivity.java
├── jniLibs
│   ├── arm64-v8a
│   │   └── libhello_world.so
│   ├── armeabi-v7a
│   │   └── libhello_world.so
│   ├── x86
│   │   └── libhello_world.so
│   └── x86_64
│       └── libhello_world.so
└── res
    ├── layout
    │   └── activity_main.xml
    ├── mipmap-hdpi
    │   ├── ic_launcher.png
    │   └── ic_launcher_round.png
    ├── mipmap-mdpi
    │   ├── ic_launcher.png
    │   └── ic_launcher_round.png
    ├── mipmap-xhdpi
    │   ├── ic_launcher.png
    │   └── ic_launcher_round.png
    ├── mipmap-xxhdpi
    │   ├── ic_launcher.png
    │   └── ic_launcher_round.png
    ├── mipmap-xxxhdpi
    │   ├── ic_launcher.png
    │   └── ic_launcher_round.png
    └── values
        ├── colors.xml
        ├── dimens.xml
        ├── strings.xml
        └── styles.xml

Я загружаю библиотеку вот так

    static {
        System.loadLibrary("hello_world");
    }

Теперь я хотел бы как-нибудь без , очевидно, с папкой jniLibs в проекте android, загружать библиотеку по другому пути в системе или по URL. Представьте себе, например, что содержимое папки jniLibs находится в каталоге /tmp. Как мне указать это в приложении, чтобы его можно было найти во время выполнения?

Возможно ли это, и если да, то как?

1 Ответ

1 голос
/ 09 мая 2019

В каком-то смысле ваша задача тривиальна. Java определяет System.load(), который должен работать как

System.load("/tmp/libhello_world.so");

В отличие от loadLibrary(), здесь вы явно указываете путь, и имя не обязательно должно начинаться с lib и заканчиваться .so. Тем не менее система может накладывать другие ограничения на путь, с которого может быть загружена библиотека. Например. вы не можете загрузить библиотеку из внешнего хранилища , т.е. /sdcard. Только системные приложения имеют право загружать библиотеки из /system/libs (за исключением нескольких библиотек, занесенных в белый список).

Но, как объяснил @CommonsWare в своем комментарии, требования Google Play Store и других установленных каналов распространения приложений не позволяют загружать библиотеки или иным образом выполнять двоичные файлы, которые не поступают из их (Google Play и т. Д.) Защищенных каналов. .

Что касается папки jniLinbs, это не единственный способ добавить нативные библиотеки в APK или комплект. Существуют различные способы заставить gradle добавить некоторые файлы в раздел libs, чтобы приложение на устройстве могло загружать их с System.load().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...