【问题标题】:Android Provider in Dynamic Feature module not found in Base Module在基本模块中找不到动态功能模块中的 Android 提供程序
【发布时间】:2020-03-31 23:09:26
【问题描述】:

我在我的动态功能模块中使用了一些库。这些库正在向清单中添加一些提供程序。

例如在我的 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>

问题是当我构建我的基本模块时,应用程序崩溃了,因为它找不到提供程序。我该如何解决这个问题?

正如here所说:

您应用的基本模块的清单与任何其他应用模块的清单相似。请记住,当 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) 

【问题讨论】:

  • 发布完整的堆栈跟踪和用于访问提供程序的代码
  • @pskink 我发布了完整的堆栈跟踪。我不在我的基本模块中访问此提供程序。我的基本模块是一个空模块,仅用于测试。只是启动器的一个空活动。
  • 你确定你的 apk 中有 com.esafirm.imagepicker.helper.ImagePickerFileProvider 类吗?
  • 这个问题你解决了吗?我也有同样的问题,还没解决。
  • @FruitAddict 我认为目前唯一的解决方案是将依赖项添加到基本模块。我找不到其他解决方案。

标签: android android-manifest android-app-bundle dynamic-feature dynamic-delivery


【解决方案1】:

试试这个解决方案。

在您的应用 build.gradle 中添加带有 tools:node="remove" 的提供程序

<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

【讨论】:

  • 感谢您的回答。这似乎是一个聪明的主意。但是安装动态模块后是否有效?
  • 是的,我可以确认它适用于我的动态模块。你试过了吗?
  • 基础 apk 没问题,但功能 apk 也缺少提供者,因此无法注册
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 1970-01-01
相关资源
最近更新 更多