Dynamic module feature and ML Kit Crash on App open
Asked Answered
I

4

5

App has ML Kit functionality (translation). I'm trying to reduce the app size by introducing a dynamic module feature, on demand loading.

Following this guide Added 'com.google.mlkit:playstore-dynamic-feature-support:16.0.0-beta1' to base apk's build.gradle

com.google.mlkit:translate:16.1.2 in feature module build.gradle,

everything compiles and tries to run on emulator, but unfortunately crashes on app start with log

java.lang.RuntimeException: Unable to get provider com.google.mlkit.common.internal.MlKitInitProvider: com.google.firebase.components.MissingDependencyException: Unsatisfied dependency for component Component<[class com.google.android.gms.internal.mlkit_translate.zzxa]>{0, type=0, deps=[Dependency{anInterface=class com.google.mlkit.common.sdkinternal.SharedPrefManager, type=required, injection=direct}, Dependency{anInterface=class com.google.android.gms.internal.mlkit_translate.zzwx, type=required, injection=direct}]}: class com.google.mlkit.common.sdkinternal.SharedPrefManager

 Caused by: com.google.firebase.components.MissingDependencyException: Unsatisfied dependency for component Component<[class com.google.android.gms.internal.mlkit_translate.zzxa]>{0, type=0, deps=[Dependency{anInterface=class com.google.mlkit.common.sdkinternal.SharedPrefManager, type=required, injection=direct}, Dependency{anInterface=class com.google.android.gms.internal.mlkit_translate.zzwx, type=required, injection=direct}]}: class com.google.mlkit.common.sdkinternal.SharedPrefManager
    

Which kind of does not make sense. Because I've added playstore-dynamic-feature-support.

Indiscipline answered 27/6, 2021 at 17:4 Comment(2)
Did you get any solution?Display
no, had to abandon this ideaIndiscipline
T
6

If someone is still not able to figure out using @Shane Gallagher's answer I am detailing out the steps: First as mentioned add Provider in app module to disable MlKit initialization:

<provider
        android:name="com.google.mlkit.common.internal.MlKitInitProvider"
        android:authorities="${applicationId}.mlkitinitprovider"
        tools:node="remove"/>

Next build apk and open your merged manifest. Find all the component registrars used in your app. You can open merged manifest by clicking on merged manifest text in bottom left corner of Android Studio after opening AndroidManifest.xml

image for reference

Next in your dynamic feature module add the following code as per the registrars used in your app

val registrars = listOf(CommonComponentRegistrar(), VisionCommonRegistrar(), BarcodeRegistrar())
MlKitContext.initialize(this, registrars)
Terrarium answered 7/3, 2022 at 8:5 Comment(4)
Just curious, will it work without disabling MlKit initialization if you remove all mlkit dependencies except com.google.mlkit:playstore-dynamic-feature-support from app's gradle file.Anatolia
Nope, I had tried that first, it still kept crashing, the documentation is also not very clear on thisTerrarium
Were you able to reproduce it locally with these instructions? developer.android.com/guide/playcore/feature-delivery/…Anatolia
Reproduce as in? The dynamic delivery part? Or the failure part? I had to abandon this idea as there is no api exposed to prevent reinitialisation and it gave an exception when it MLKit initialised againTerrarium
P
5

Figured it out,

Step 1. disable MlKitInitProvider in app module (stops app crash)

<provider
android:name="com.google.mlkit.common.internal.MlKitInitProvider"
            android:authorities="${applicationId}.mlkitinitprovider"
            tools:node="remove"
            />

Step 2. build apk and open the app manifest, find all MLKit Registrars used in your app. Step 3. add all found to a ComponentRegistrar array ArrayList; Step 4. In the dynamic feature library, call MlKitContext.initialize(context, arr); (in getProvider the service provider) prior to using mlkit functionality;

Also, only using these mlkit dependencies in app module (for split install) api group: 'com.google.mlkit', name: 'common', version: '17.5.0' api group: 'com.google.mlkit', name: 'playstore-dynamic-feature-support', version: '16.0.0-beta1'

Penetralia answered 17/1, 2022 at 18:26 Comment(0)
D
1

To set up your dynamic module, you will need to move the mlkit translate dependency from the base app's gradle file to the dynamic module's gradle build file. You will also need to move all related usage to the dynamic module. Therefore, when app start up, it won't look for any mlkit translate dependency. Please refer to the play store on demand delivery guide for step to step set up guidance.

Driblet answered 29/6, 2021 at 22:3 Comment(0)
C
0

I know this is bit old to post now. But I faced many issues related to moving Mlkit feature as dynamic feature module.

Makesure the following:-

App/Base Module AndroidManifest

 <provider
    android:name="com.google.mlkit.common.internal.MlKitInitProvider"
        android:authorities="${applicationId}.mlkitinitprovider"
        tools:node="remove"
   />

Base/App build.gradle

 "com.google.mlkit:common"  and com.google.mlkit:playstore-dynamic-feature-support in base module build gradle.

Dynamic Feature Module

Add feature specific library like barcode or face capture in dynamic module.

 example com.google.mlkit:barcode-scanning and com.google.mlkit:face-detection in dynamic feature module.

Initialise MLKit in dynamic feature module

Make sure you have initialise Mlkit in dynamic module with the component list.

Example

 val registrars = listOf(CommonComponentRegistrar(), BarcodeRegistrar(), FaceRegistrar(), VisionCommonRegistrar())
        MlKitContext.initialize(this, registrars)

The list of component name you can get it from the base/app module AndroidManifest.xml once the apk has been created (Do analyse the apk after build process).

Cutup answered 5/6 at 6:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.