11

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.
sagis
  • 2,162
  • 18
  • 24
  • Are you using WorkManager in your application? If yes are you using a custom configuration? – pfmaggi Oct 30 '20 at 11:32
  • @pfmaggi Not using WorkManager directly. Downgrading AdMob 19.5.0 to 19.4.0 removed the WorkManager dependency. No custom configuration. The only thing that comes to mind is the fact I use app bundle. It could be an issue with an old WorkManager since AdMob 19.5.0 adds dependency on WorkManager 2.1.0, while the latest version is 2.4.0. – sagis Oct 31 '20 at 09:16
  • Please open a bug on the WorkManager public issue tracker: https://issuetracker.google.com/issues/new?component=409906&template=1094197 – pfmaggi Nov 02 '20 at 20:19
  • @pfmaggi It's a rare issue and probably very hard to reproduce. If no one up vote this question I can't be sure it's the SDK fault and not something specific in my app. – sagis Nov 04 '20 at 07:54
  • Understood. Given that WorkManager uses the classnames to instantiate Workers, a possible problem could be related to R8/Proguard that remove/rename some of the classes (but the error is for the initializer... so this is shot in the dark). Without additional information is it hard to say what it is going on. – pfmaggi Nov 04 '20 at 07:58
  • @pfmaggi The error appeared only in a small number of devices (about ~0.1%). I also thought about R8, so I checked the DEX file and the class was there. – sagis Nov 05 '20 at 08:33

3 Answers3

22

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" />
Chivorn
  • 2,203
  • 2
  • 21
  • 37
6

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:

  1. Remove WorkManager from the App Startup provider.
  2. 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);
sagis
  • 2,162
  • 18
  • 24
-1

Why not just add this line to your proguard file?

-keep class androidx.work.** { *; }
Justin
  • 17,670
  • 38
  • 132
  • 201
  • The class exist in the DEX, it's not a ProGuard/R8 issue (see my answer to @pfmaggi in the question comments). – sagis Jan 14 '21 at 15:17