Android Provider in Dynamic Feature module not found in Base Module

泄露秘密 提交于 2021-01-27 03:43:41

问题


I am using some libraries in my dynamic feature module. These libraries are Adding some providers to the manifest.

For example in my build.gradle file in the dynamic module:

dependencies {
    ...
    implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1'
    ...
}

This library adds the following tag to the manifest:

<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>

The problem is when I build my base module the app crashes because it cannot find the provider. How can I solve this?

As it is stated here:

The manifest for your app’s base module is similar to that of any other app module. Keep in mind, when Google Play generates your app’s base APK, it merges manifests for all modules into that of the base APK.

But why only providers are affected? Are activities ignored?

This is the stacktrace I get:

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:


Try this solution.

Add provider with tools:node="remove" in you app 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>

In Android Studio it will be marked as red but when you build bundle with

./gradlew clean bundleRelease 

it should finish with success.

Now you can generate .apks file and unzip it:

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

After this you can decode your .apk files (for example with apktool) to take a look at their manifests. Now in base-master.apk you shouldn't see your provider entries, and in {dynamic-module}master.apk it should be available.

java -jar apktool_2.4.0.jar d release/splits/base-master.apk


来源:https://stackoverflow.com/questions/55772461/android-provider-in-dynamic-feature-module-not-found-in-base-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!