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

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

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

Я пытался установить с помощью 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 ..

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

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

18
0
4 119
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

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

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

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

Спасибо за ответ. Есть ли какой-то стандартный способ получить байтовое смещение родной библиотеки из apk? Я предполагаю, что Google хочет, чтобы мы использовали System.loadLibrary(), но как насчет двоичных файлов, использующих общие библиотеки? Это сейчас совсем не поддерживается?

Elad Levin 12.06.2019 00:12

Возможно, мне просто нужно добавить эту библиотеку в качестве актива, если я использую ее напрямую (вы правы, это сторонняя библиотека, иначе я бы статически свяжу ее)

Elad Levin 12.06.2019 00:18

Чтобы найти общую библиотеку в вашем APK, вы можете использовать файл AssetManager.openNonAssetFd(). Вместо dlopen() вы должны использовать специфичный для платформы android_dlopen_ext() и передать дескриптор и смещение АссетФайлДескриптор. Обратите внимание, что Управляющий активами также имеет родной API.

Alex Cohn 12.06.2019 08:43

Я верю, что вы также можете сделать dlopen("/path/to/MyApp.apk!libfoo.so", ...). Если это не сработает, не могли бы вы сообщить об ошибке? Мы должны убедиться, что есть простой способ сделать это (я думаю, что, вероятно, должен быть API, который просто «открывает эту библиотеку из моего APK», поэтому вам не нужно выяснять путь к вашему файлу APK... ошибка, запрашивающая API, если это то, что вам нужно)

Dan Albert 14.06.2019 01:07

@DanAlbert, согласно этот ответ, вы можете вызвать System.loadLibrary() из java, и тогда dlsym(0,..) будет работать с любой загруженной библиотекой. Не уверен, работает ли это для процессов, порожденных с помощью exec(), или только для вызовов JNI. Вы также можете попробовать вызвать команду loadLibrary() java из своего собственного кода.

Elad Levin 15.06.2019 03:09

@EladLevin, спасибо, что поделились моим ответом. Приятным бонусом является то, что System.loadLibrary() прозрачно работает с нераспакованными библиотеками. К сожалению, эти библиотеки нельзя использовать совместно с порожденными исполняемыми файлами.

Alex Cohn 17.06.2019 13:03

На самом деле, как указал @DanAlbert в другом месте, вы можете просто использовать dlopen(libfoo.so), и это будет автоматически искать библиотеку во всех поддерживаемых местах, включая не извлеченные из APK или App Bundle.

Alex Cohn 14.08.2019 22:11

Я думаю, что на самом деле это не работает, если библиотека не извлечена... но так и должно быть. Подано github.com/android-ndk/ndk/issues/1061

Dan Albert 14.08.2019 22:53

Другие вопросы по теме