ClassNotFoundException: “androidx.work.impl.WorkManagerInitializer”
A new exception appeared on some devices after upgrading Google AdMob Ads library version 19.4.0 to 19.5.0:
Caused by java.lang.ClassNotFoundException
Didn't find class "androidx.work.impl.WorkManagerInitializer" on path: ...
dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:196)
androidx.core.app.CoreComponentFactory.instantiateProvider (CoreComponentFactory.java)
android.app.ActivityThread.installProvider (ActivityThread.java:7213)
android.app.ActivityThread.installContentProviders (ActivityThread.java:6769)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:941)
The exception appeared on devices with Android 8 & 10.
AdMob library 19.5.0 adds dependency on WorkManager 2.1.0 (via Play Services Ads Lite library): https://mvnrepository.com/artifact/com.google.android.gms/play-services-ads-lite/19.5.0
There is a similar question on this issue, but it seems to be unrelated (older Android OS versions with multiple dex, while here it's single dex and newer OS versions).
For now I downgraded to AdMob 19.4.0, which does not include WorkManager dependency.
Update (2020.12.18)
- The exception frequency is 1 per 1000 devices running Android 10.
- Forcing WorkManager 2.4.0 (instead of 2.1.0) also generates the exception.
- The issue is unrelated to AdMob. Adding WorkManager to the project with AdMob 19.4.0 reproduced the issue.
- My current assumption is that the issue is caused by a collision between the content providers of AudienceNetwork & WorkManager. Adding AudienceNetwork to a project with WorkManager
generated a same exception, with a different class:
Didn't find class "com.facebook.ads.AudienceNetworkContentProvider"
on some Android 10 devices.
Solution 1:
From Google document start from version 2.6.0-alpha01
, WorkManager
uses androidx.startup
to initialize WorkManager. Previously, this was being done by androidx.work.impl.WorkManagerInitializer
If you used tools:node="remove"
the ContentProvider
being used to initialize process lifecycle in the past, then you need to do the following instead.
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.impl.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
Or
<!-- If you want to disable android.startup completely. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
Solution 2:
Workaround: manual initialization of WorkManager does not cause this exception.
AdMob 20.5.0 and above (or explicit dependency of WorkManager 2.6.0+)
WorkManager now uses App Startup provider. In order to use manual init:
- Remove WorkManager from the App Startup provider.
- Add WorkManager configuration to the Application object.
Step 1: There are 2 ways to remove WorkManager from the App Startup provider:
- Removing the entire provider. or
- Remove only WorkManager.
From the documentation of WorkManager:
<!-- If you want to disable android.startup completely. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>
Or
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
Step 2: Add manual WorkManager configuration in the Application object:
class MyApplication extends Application implements Configuration.Provider {
@NonNull
@Override
public Configuration getWorkManagerConfiguration() {
return new Configuration.Builder()
.build();
}
}
AdMob 20.4.0 and below
Remove the WorkManager default content provider initialization by adding the following to the Manifest.xml
:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove"
android:exported="false"
/>
Add manual initialization of the WorkManager to the Application.onCreate()
method:
Configuration myConfig = new Configuration.Builder()
.build();
WorkManager.initialize(this, myConfig);