工作管理器 - 当我们同时使用默认初始化和自定义初始化时,我们是否应该删除默认初始值设定项?



当我将工作管理器从"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课。

我的应用程序类

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();
}
}

我如何构建工作管理器

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);
}
}

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

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

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

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

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

我们在WorkManager2.3.0-*中引入了这个lint规则。我们试图用这个 Lint 规则解决的问题是,如果你同时有WorkManagerInitializerContentProvider,并且你的Application子类型实现了Configuration.Provider(用于按需初始化(,则ContentProvider始终优先。

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

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

是的,您需要像要使用按需初始化一样删除默认的工作管理器初始值设定项,因此请在清单中保留以下代码段:

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

此外,上面的文档清楚地指出你不应该调用WorkManager.getInstance()(没有Context参数(:

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

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

  • 添加了一个 lint 规则,该规则可确保在使用按需初始化时从 AndroidManifest 中删除内容提供程序 androidx.work.impl.WorkManagerInitializer.xml。(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);
}
}

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

如果有的话,你可以为你的内容提供商做一些等效的事情。

PS:有趣的代码实验室教程退出 java 或 kotlin

WorkManagerInitializer用于提供WorkManager的上下文。发生这种情况是因为内容提供程序在Application之前初始化(请参阅此问题(。这就是在执行自定义初始化时需要自己提供上下文的原因。因此,如果使用自定义初始化,则不需要它。

如果从内容提供程序调用getWorkManager方法,则应用程序实例将null。若要解决此问题,只需通过在内容提供程序中调用getContext,将上下文作为参数传递给方法:

public static WorkManager getWorkManager(Context context) {
return WorkManager.getInstance(context);
}
public class MyContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
WorkManager workManager = getWorkManager(getContext());
...
}
...
}

最新更新