4

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.

toasty
  • 142
  • 1
  • 1
  • 10

3 Answers3

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'

4

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)
sanket vetkoli
  • 826
  • 14
  • 18
  • 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. – zhouyi Mar 19 '22 at 00:08
  • 1
    Nope, I had tried that first, it still kept crashing, the documentation is also not very clear on this – sanket vetkoli Mar 22 '22 at 12:47
  • Were you able to reproduce it locally with these instructions? https://developer.android.com/guide/playcore/feature-delivery/on-demand#local-testing – zhouyi May 12 '22 at 21:10
  • 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 again – sanket vetkoli Jun 07 '22 at 03:25
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.

Chenxi Song
  • 557
  • 3
  • 6