WorkManager - 当我们同时使用默认初始化和自定义初始化时,我们是否应该删除默认初始化程序?

Che*_*eng 10 android android-workmanager androidx

当我将 WorkManager 从“2.2.0”升级到“2.3.0-rc01”时,出现以下新错误

当我导出 APK 时发生错误。

C:\app: Error: Remove androidx.work.impl.WorkManagerInitializer from your AndroidManifest.xml when using on-demand initialization. [RemoveWorkManagerInitializer]

   Explanation for issues of type "RemoveWorkManagerInitializer":
   If an android.app.Application implements
   androidx.work.Configuration.Provider,
   the default androidx.work.impl.WorkManagerInitializer needs to be removed
   from the
   AndroidManifest.xml file.
Run Code Online (Sandbox Code Playgroud)

我不知道为什么我在 2.2.0 中没有收到这样的错误,因为从 2.1.0 开始引入了“按需初始化”。

根据https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration#remove-default

我不确定将以下内容包含在我的AndroidManifest.xml.

<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove" />
Run Code Online (Sandbox Code Playgroud)

目前,以下是我的Application班级。

MyApplication 类

public class MyApplication extends MultiDexApplication implements Configuration.Provider {
    private static MyApplication me;

    @Override
    public void onCreate() {
        super.onCreate();

        me = this;
    }

    public static MyApplication instance() {
        return me;
    }

    @NonNull
    @Override
    public Configuration getWorkManagerConfiguration() {
        return new Configuration.Builder()
                .build();
    }
}
Run Code Online (Sandbox Code Playgroud)

我如何构建 WorkManager

public static WorkManager getWorkManager() {
    MyApplication myApplication = MyApplication.instance();
    if (myApplication == null) {
        // Very rare edge case. Not sure how it happens. But, it happens :)
        return WorkManager.getInstance();
    } else {
        return WorkManager.getInstance(myApplication);
    }
}
Run Code Online (Sandbox Code Playgroud)

WorkManager.getInstance()Application类为空时,似乎也很少有机会执行“默认初始化”()。

我可以通过包含以下内容轻松消除 APK 导出过程中的错误provider。但是,这样做是对的吗?

<provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    tools:node="remove" />
Run Code Online (Sandbox Code Playgroud)

apa*_*luk 22

如果您在更新到 2.6.0 或更高版本后收到此错误WorkManager,则必须在清单中使用以下代码段:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">

    <meta-data
        android:name="androidx.work.WorkManagerInitializer"
        android:value="androidx.startup"
        tools:node="remove" />

</provider>
Run Code Online (Sandbox Code Playgroud)


Rah*_*hul 12

我们在 WorkManager 中引入了这个 lint 规则2.3.0-*。我们试图用此 Lint 规则解决的问题是,如果您同时拥有WorkManagerInitializer ContentProvider和您的Application子类型实现Configuration.Provider(用于按需初始化) - 则ContentProvider始终优先

这可能是意想不到的,特别是当您有其他Configuration不会生效的情况时,因为ContentProvider 总是使用默认配置。

您真正需要做的就是删除默认提供程序。这样初始化将不再是急切的,而是按需的。


Gom*_*ino 7

是的,如果您想使用按需初始化,您需要删除默认的工作管理器初始化程序,因此请在清单中保留以下代码:

<provider
   android:name="androidx.work.impl.WorkManagerInitializer"
   android:authorities="${applicationId}.workmanager-init"
   tools:node="remove" />
Run Code Online (Sandbox Code Playgroud)

另外,上面的文档明确指出您不应该调用WorkManager.getInstance()(没有Context参数):

注意:如果在初始化 WorkManager 之前调用已弃用的无参数 WorkManager.getInstance() 方法,该方法将引发异常。您应该始终使用 WorkManager.getInstance(Context) 方法,即使您没有自定义 WorkManager。

查看 androix/work 变更日志后,您将看到版本2.3.0-beta02中添加了一个新功能:

  • 添加了 lint 规则,确保在使用按需初始化时从 AndroidManifest.xml 中删除内容提供程序 androidx.work.impl.WorkManagerInitializer。(aosp/1167007

从版本 2.2.0 升级到 2.3.0.rc1 后出现此错误的原因是,android 团队添加了一个RemoveWorkManagerInitializerDetector ,它将抛出您在构建时在以下拉取请求中遇到的异常。

现在关于源代码,我建议您getWorkManager直接将方法紧固到应用程序,如下所示:

import androidx.annotation.NonNull;
import androidx.work.Configuration;
import androidx.work.WorkManager;

public class App extends MultiDexApplication implements Configuration.Provider {
    private static App APP_INSTANCE;

    @Override
    public void onCreate() {
        super.onCreate();
        APP_INSTANCE = this;
    }

    public static App getInstance() {
        return APP_INSTANCE;
    }

    @NonNull
    @Override
    public Configuration getWorkManagerConfiguration() {
        return new Configuration.Builder()
                .build();
    }

    public static WorkManager getWorkManager() {
        return WorkManager.getInstance(APP_INSTANCE);
    }
}
Run Code Online (Sandbox Code Playgroud)

只需App.getWorkManager()在应用程序源代码中需要时调用即可

如果有的话,您可以为您的 ContentProvider 做一些等效的事情。

PS:针对javakotlin存在有趣的 Codelabs 教程