ClassNotFoundException:“androidx.work.impl.WorkManagerInitializer”

ClassNotFoundException: “androidx.work.impl.WorkManagerInitializer”

升级 Google AdMob 广告库版本 19.4.0 至 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)

异常出现在 Android 8 和 10 的设备上。

AdMob 库 19.5.0 添加了对 WorkManager 2.1.0 的依赖(通过 Play Services Ads Lite 库): https://mvnrepository.com/artifact/com.google.android.gms/play-services-ads-lite/19.5.0

关于这个问题有一个 ,但它似乎是无关的(旧的 Android OS 版本有多个 dex,而这里是单个 dex 和新的 OS 版本).

现在我降级到 AdMob 19.4.0,它不包括 WorkManager 依赖项。

更新 (2020.12.18)

解决方法: manual initialization of WorkManager 不会导致此异常。

AdMob 20.5.0 及更高版本(或明确依赖 WorkManager 2.6.0+)

WorkManager 现在使用 App Startup 提供程序。为了使用手动初始化:

  1. 从应用程序启动提供程序中删除 WorkManager。
  2. 将 WorkManager 配置添加到应用程序对象。

第 1 步: 有两种方法可以从 App Startup provider 中删除 WorkManager:

  • 正在删除整个提供程序。 或
  • 仅删除 WorkManager。

来自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>

或者

 <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>

第 2 步: 在 Application 对象中添加手动 WorkManager 配置:

class MyApplication extends Application implements Configuration.Provider {
    @NonNull
    @Override
    public Configuration getWorkManagerConfiguration() {
        return new Configuration.Builder()
                .build();
    }
}

AdMob 20.4.0 及更低版本

通过将以下内容添加到 Manifest.xml 来删除 WorkManager 默认内容提供程序初始化:

<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove"
    android:exported="false"
    />

Application.onCreate()方法中添加WorkManager的手动初始化:

Configuration myConfig = new Configuration.Builder()
        .build();
WorkManager.initialize(this, myConfig);

为什么不直接将这一行添加到您的 proguard 文件中?

-keep class androidx.work.** { *; }

Google document版本2.6.0-alpha01开始,WorkManager使用androidx.startup初始化WorkManager。以前,这是由 androidx.work.impl.WorkManagerInitializer 完成的 如果您过去使用 tools:node="remove"ContentProvider 来初始化进程生命周期,那么您需要改为执行以下操作。

<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>

<!-- If you want to disable android.startup completely. -->
<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />