#android #android-manifest #android-app-bundle #dynamic-feature #dynamic-delivery
#Android #android-манифест #android-app-bundle #динамическая функция #динамическая доставка
Вопрос:
Я использую некоторые библиотеки в своем модуле динамических функций. Эти библиотеки добавляют некоторые поставщики в манифест.
Например, в моем файле build.gradle в динамическом модуле:
dependencies {
...
implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1'
...
}
Эта библиотека добавляет следующий тег в манифест:
<provider
android:name="com.esafirm.imagepicker.helper.ImagePickerFileProvider"
android:authorities="{$applicationId}.imagepicker.provider"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/image_picker_provider_paths" />
</provider>
Проблема в том, что когда я создаю свой базовый модуль, приложение выходит из строя, потому что оно не может найти поставщика. Как я могу это решить?
Как указано здесь:
Манифест для базового модуля вашего приложения аналогичен манифесту любого другого модуля приложения. Имейте в виду, что когда Google Play генерирует базовый APK-файл вашего приложения, он объединяет манифесты для всех модулей в базовый APK.
Но почему затронуты только поставщики? Игнорируются ли действия?
Это трассировка стека, которую я получаю:
java.lang.RuntimeException: Unable to get provider com.esafirm.imagepicker.helper.ImagePickerFileProvider: java.lang.ClassNotFoundException: Didn't find class "com.esafirm.imagepicker.helper.ImagePickerFileProvider" on path: DexPathList[[zip file "/data/app/ir.rashin.mototel-h7B8g42gBcVABkik16vqzw==/base.apk"],nativeLibraryDirectories=[/data/app/ir.rashin.mototel-h7B8g42gBcVABkik16vqzw==/lib/x86, /system/lib]]
at android.app.ActivityThread.installProvider(ActivityThread.java:6396)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853)
at android.app.ActivityThread.access$1100(ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.esafirm.imagepicker.helper.ImagePickerFileProvider" on path: DexPathList[[zip file "/data/app/ir.rashin.mototel-h7B8g42gBcVABkik16vqzw==/base.apk"],nativeLibraryDirectories=[/data/app/ir.rashin.mototel-h7B8g42gBcVABkik16vqzw==/lib/x86, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:121)
at android.support.v4.app.CoreComponentFactory.instantiateProvider(CoreComponentFactory.java:62)
at android.app.ActivityThread.installProvider(ActivityThread.java:6380)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:5938)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5853)
at android.app.ActivityThread.access$1100(ActivityThread.java:199)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Комментарии:
1. опубликуйте полную трассировку стека и код, который вы используете для доступа к своему провайдеру
2. @pskink я опубликовал полную трассировку стека. Я не обращаюсь к этому поставщику в своем базовом модуле. Мой базовый модуль — это пустой модуль только для тестирования. Просто пустое действие для launcher.
3. и вы уверены, что у вас есть класс
com.esafirm.imagepicker.helper.ImagePickerFileProvider
в вашем apk?4. Вы решили эту проблему? У меня такой же, и я еще не решил его.
5. @FruitAddict Я думаю, что единственным решением на данный момент было бы добавить зависимость к базовому модулю. Я не смог найти другого решения.
Ответ №1:
Попробуйте это решение.
Добавьте поставщика с tools:node="remove"
помощью вашего приложения build.gradle
<provider
android:name="com.esafirm.imagepicker.helper.ImagePickerFileProvider"
android:authorities="{$applicationId}.imagepicker.provider"
android:exported="false"
android:grantUriPermissions="true"
tools:node="remove" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/image_picker_provider_paths" />
</provider>
В Android Studio он будет отмечен красным, но когда вы создаете пакет с
./gradlew clean bundleRelease
он должен завершиться успешно.
Теперь вы можете сгенерировать файл .apk и разархивировать его:
java -jar bundletool-all-0.10.2.jar build-apks --bundle=app.aab --output=release.apks --ks=release.keystore --ks-pass=pass:xxxxxx --ks-key-alias=xxxxxxkey --key-pass=pass:xxxxxx
unzip release.apks
После этого вы можете декодировать свои файлы .apk (например, с помощью apktool), чтобы взглянуть на их манифесты.
Теперь в base-master.apk вы не должны видеть записи вашего поставщика, а в {dynamic-module} master.apk он должен быть доступен.
java -jar apktool_2.4.0.jar d release/splits/base-master.apk
Комментарии:
1. Спасибо за ваш ответ. Это кажется умной идеей. Но работает ли он при установке динамического модуля?
2. Да, я могу подтвердить, что он работает для моего динамического модуля. Вы пробовали это?
3. Базовый apk в порядке, но в apk функций также отсутствует поставщик, поэтому он не будет зарегистрирован