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

时间:2020-01-13 03:42:57

标签: android androidx android-workmanager

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

我不确定为什么在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" />

当前,以下是我的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();
    }
}

我如何构造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);
    }
}

WorkManager.getInstance()类为null时,似乎也极有可能执行“默认初始化”(Application)。

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

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

3 个答案:

答案 0 :(得分:3)

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

这可能是意外的,尤其是当您有其他{em>不会生效的Configuration时,因为ContentProvider 总是使用默认配置。

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

答案 1 :(得分:3)

是的,您需要像使用on-demand initialization一样删除默认的工作管理器初始化程序,因此请在清单中保留以下代码:

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

以上文档也明确指出您不应该调用WorkManager.getInstance()(没有Context参数):

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

查看androix /工作变更日志后,您会发现版本2.3.0-beta02中添加了新功能:

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

从版本2.2.0升级到2.3.0.rc1后出现此错误的原因是,Android团队添加了RemoveWorkManagerInitializerDetector,它将引发以下{{3} }。

现在关于源代码,我建议您像下面这样直接将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);
    }
}

然后只要需要在应用程序源代码中调用App.getWorkManager()

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

PS:pull requestjava的有趣的代码实验室教程退出

答案 2 :(得分:0)

>>> import TheModuleInQuestion >>> print(TheModuleInQuestion) 用于为WorkManagerInitializer提供上下文。发生这种情况是因为内容提供者在WorkManager之前初始化(请参见this question)。因此,如果您进行自定义初始化,则需要自己提供上下文。因此,如果您使用自定义初始化,则不需要它。

如果您要从content provider调用Application方法,则您的应用程序实例将为getWorkManager。要解决此问题,只需在内容提供者内部调用null,将上下文作为参数传递给方法:

getContext
public static WorkManager getWorkManager(Context context) {
    return WorkManager.getInstance(context);
}