Поставщик Android в модуле динамических функций не найден в базовом модуле

Я использую некоторые библиотеки в своем модуле динамических функций. Эти библиотеки добавляют в манифест некоторых поставщиков.

Например, в моем файле 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) 

person Saeed Entezari    schedule 20.04.2019    source источник
comment
опубликуйте полную трассировку стека и код, который вы используете для доступа к вашему провайдеру   -  person pskink    schedule 20.04.2019
comment
@pskink Я выложил полную трассировку стека. У меня нет доступа к этому провайдеру в моем базовом модуле. Мой базовый модуль - это пустой модуль только для тестирования. Просто пустая активность для лаунчера.   -  person Saeed Entezari    schedule 20.04.2019
comment
а ты уверен, что у тебя в апк класс com.esafirm.imagepicker.helper.ImagePickerFileProvider?   -  person pskink    schedule 20.04.2019
comment
@pskink Сэр, этого класса нет в моем apk. Этот класс добавляется зависимостью модуля динамических функций. Но это добавлено в манифест динамического, который объединен с манифестом базового модуля. Это источник ошибки. потому что класс не добавлен в apk базового модуля, но существует в манифесте.   -  person Saeed Entezari    schedule 20.04.2019
comment
Вы решили эту проблему? У меня есть такая же, и я ее еще не решил.   -  person FruitAddict    schedule 13.08.2019
comment
@FruitAddict Я думаю, что на данный момент единственным решением было бы добавить зависимость к базовому модулю. Я не мог найти другого решения.   -  person Saeed Entezari    schedule 14.08.2019
comment
Я встретил такую ​​же проблему Y_Y   -  person Hien Nguyen    schedule 10.02.2021


Ответы (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 

он должен закончиться успешно.

Теперь вы можете сгенерировать файл .apks и разархивировать его:

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
person user3001276    schedule 14.08.2019
comment
Спасибо за ваш ответ. Похоже на умную идею. Но работает ли он, когда установлен динамический модуль? - person Saeed Entezari; 14.08.2019
comment
Да, я могу подтвердить, что это работает для моего динамического модуля. Вы пробовали? - person user3001276; 18.08.2019
comment
Базовый apk в порядке, но у функции apk тоже отсутствует поставщик, поэтому он не будет зарегистрирован - person Kamer358; 20.11.2019