Собственные библиотеки не найдены в ApplicationInfo.nativeLibraryDir при сборке пакета приложений для телефона arm64 Android

Я пытаюсь перенести свое приложение из монолитного APK в формат пакета приложений. Мне нужно установить переменную среды LD_LIBRARY_PATH для вызова exec(), поэтому мне нужно расположение моих собственных библиотек. В исходном APK я бы назвал getApplicationInfo().nativeLibDir, и библиотеки были там.

С пакетом приложений их нет. Я вижу, что установлен правильный APK-файл с разделением abi, но по какой-то причине библиотеки не извлекаются.

Я пробовал установить с bundletool и через Google Play,

Пытался запустить 'ls -alR', и я ясно вижу, что каталог существует, а также разделенный apk, но библиотеки просто не извлекаются. Думаю, я мог бы извлечь их вручную в качестве обходного пути, но это могло бы показаться ненужным ..?

Вот результат ls в родительской папке для nativeLibPath

genLibraryPath: Dir Contents: /data/app/com.unseenonline-raAFLhJMQpjqWkVdG1Vocg==:
        total 16704
        drwxr-xr-x   4 system system      4096 2019-06-11 12:41 .
        drwxrwx--x 114 system system     12288 2019-06-11 12:41 ..
        -rw-r--r--   1 system system   5688352 2019-06-11 12:41 base.apk
        drwxr-xr-x   3 system system      4096 2019-06-11 12:41 lib
        drwxrwx--x   3 system install     4096 2019-06-11 12:41 oat
        -rw-r--r--   1 system system  11226112 2019-06-11 12:41 split_config.arm64_v8a.apk
        -rw-r--r--   1 system system     35636 2019-06-11 12:41 split_config.en.apk
        -rw-r--r--   1 system system     90443 2019-06-11 12:41 split_config.xxhdpi.apk

        /data/app/com.unseenonline-raAFLhJMQpjqWkVdG1Vocg==/lib:
        total 24
        drwxr-xr-x 3 system system 4096 2019-06-11 12:41 .
        drwxr-xr-x 4 system system 4096 2019-06-11 12:41 ..
        drwxr-xr-x 2 system system 4096 2019-06-11 12:41 arm64

        /data/app/com.unseenonline-raAFLhJMQpjqWkVdG1Vocg==/lib/arm64:
        total 16
        drwxr-xr-x 2 system system 4096 2019-06-11 12:41 .
        drwxr-xr-x 3 system system 4096 2019-06-11 12:41 ..

Как видите, разделенные файлы apks есть, но библиотеки не извлекаются.

Библиотеки должны быть извлечены в то же место, что и исходный apk.


person Elad Levin    schedule 11.06.2019    source источник


Ответы (1)


По умолчанию APK-файлы, сгенерированные из Android App Bundle, содержат собственные библиотеки без сжатия на устройствах с Android M / API уровня 23 или выше (источник). Это не только часто уменьшает размер загрузки, но также значительно уменьшает размер приложения на устройствах, поскольку платформа Android может напрямую читать собственные библиотеки из APK, вместо того, чтобы извлекать их в отдельное место. На последнем вводе-выводе был разговор о том, как уменьшить размер вашего приложения и как это влияет на количество установок, и они подробно рассказали, как это работает, если вы заинтересованы в том, чтобы лучше это понять.

Итак, теперь, когда вы знаете, почему Google Play делает это, у вас есть следующие возможности:

  • Вы можете вернуться к исходному поведению APK, и это можно сделать, добавив флаг android.bundle.enableUncompressedNativeLibs=false в файл gradle.properties. Это фактически отключит эту оптимизацию, что приведет к увеличению размера вашего приложения для всех пользователей M +.

  • Вы можете убедиться, что собственная библиотека загружена платформой Android (например, с помощью System.loadLibrary), или вы, если по какой-то причине читаете библиотеку непосредственно, также можете прочитать ее непосредственно из APK.

Если собственные библиотеки загружаются сторонней библиотекой, от которой вы зависите, подумайте о том, чтобы зарегистрировать для них ошибку, чтобы решить эту проблему, чтобы они следовали той же логике, что и платформа.

Надеюсь, это поможет,

person Pierre    schedule 11.06.2019
comment
Спасибо за ответ. Есть ли какой-нибудь стандартный способ получить байтовое смещение собственной библиотеки из apk? Я предполагаю, что Google хочет, чтобы мы использовали System.loadLibrary(), но как насчет двоичных файлов, использующих общие библиотеки? Это полностью не поддерживается сейчас? - person Elad Levin; 12.06.2019
comment
Возможно, мне просто нужно добавить эту библиотеку в качестве актива, если я использую ее напрямую (вы правы, это сторонняя библиотека, в противном случае я бы статически связал ее) - person Elad Levin; 12.06.2019
comment
Чтобы найти общую библиотеку в своем APK, вы можете использовать AssetManager.openNonAssetFd (). Вместо dlopen () следует использовать зависящий от платформы android_dlopen_ext () и передать дескриптор и смещение AssetFileDescriptor. Обратите внимание, что AssetManager также имеет собственный API. . - person Alex Cohn; 12.06.2019
comment
Я считаю, что вы тоже можете делать dlopen("/path/to/MyApp.apk!libfoo.so", ...). Если это не сработает, не могли бы вы сообщить об ошибке? Мы должны убедиться, что есть простой способ сделать это (я думаю, что, вероятно, должен быть API, который просто открывает эту библиотеку из моего APK, чтобы вам не нужно было выяснять путь к вашему APK ... запрашивая API, если вы этого хотите) - person Dan Albert; 14.06.2019
comment
@DanAlbert согласно этому ответу вы можете вызвать System.loadLibrary() из java, и тогда dlsym(0,..) будет работать с любой загруженной библиотекой. Не уверен, работает ли это для процессов, порожденных exec(), или только для вызовов JNI. Вы также можете попробовать вызвать loadLibrary() java-команду из собственного кода. - person Elad Levin; 15.06.2019
comment
@EladLevin, спасибо, что поделились моим ответом. Приятным бонусом является то, что System.loadLibrary() прозрачно работает с нераспакованными библиотеками. К сожалению, эти библиотеки нельзя использовать совместно с созданными исполняемыми файлами. - person Alex Cohn; 17.06.2019
comment
На самом деле, как @DanAlbert указал elsewhre, вы можете просто используйте dlopen (libfoo.so), и это автоматически выполнит поиск библиотеки во всех поддерживаемых местах, включая не извлеченные из APK или App Bundle. - person Alex Cohn; 14.08.2019
comment
Я думаю, что на самом деле это не сработает, если библиотека не извлечена ... но это должно быть. Создан github.com/android-ndk/ndk/issues/1061. - person Dan Albert; 14.08.2019