[英]WorkManager - Should we remove the default initializer, when we use both Default initialization and Custom initialization?
I'm getting the following new error, when I upgrade WorkManager from "2.2.0" to "2.3.0-rc01"当我将 WorkManager 从“2.2.0”升级到“2.3.0-rc01”时,出现以下新错误
The error occurs when I'm exporting APK.当我导出 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.
I'm not sure why I didn't get such error in 2.2.0, as "On-Demand Initialization" is introduced since 2.1.0.我不知道为什么我在 2.2.0 中没有收到这样的错误,因为从 2.1.0 开始引入了“按需初始化”。
According to https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration#remove-default根据https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration#remove-default
I'm not kinna sure, whether it is a right thing to include the following in my AndroidManifest.xml
.我不确定在我的
AndroidManifest.xml
包含以下内容是否正确。
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
Currently, the following is my Application
class.目前,以下是我的
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);
}
}
It seems that there is rare chance that "Default initialization" ( WorkManager.getInstance()
) is being executed too, when the Application
class is null.当
Application
类为空时,似乎也很少有机会执行“默认初始化”( WorkManager.getInstance()
)。
I can easily eliminate error during APK exporting, by including the following provider
.通过包含以下
provider
,我可以轻松消除 APK 导出过程中的错误。 But, is that a right thing to to so?但是,这样做是对的吗?
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
We introduced this lint rule in WorkManager 2.3.0-*
.我们在 WorkManager
2.3.0-*
引入了这个 lint 规则。 The problem we are trying to address with this Lint rule is that if you have both the WorkManagerInitializer
ContentProvider
and your Application
subtype implements Configuration.Provider
(for on-demand initialization) - the ContentProvider
will always take precedence.我们试图通过此 Lint 规则解决的问题是,如果您同时拥有
WorkManagerInitializer
ContentProvider
并且您的Application
子类型实现了Configuration.Provider
(用于按需初始化) - ContentProvider
将始终优先。
This might be unexpected, especially when you have additional Configuration
which will not take effect because the ContentProvider
always uses the default configuration.这可能出乎意料,尤其是当您有额外的
Configuration
不会生效时,因为ContentProvider
始终使用默认配置。
All you really need to do is to remove the default provider.您真正需要做的就是删除默认提供程序。 That way initialization will no longer be eager, but be on-demand.
这样初始化将不再是急切的,而是按需进行的。
Yes you need to remove the default work manager initializer as you did if you want to use on-demand initialization , so keep the following piece of code in your manifest:是的,如果您想使用按需初始化,您需要删除默认的工作管理器初始化程序,因此请在清单中保留以下代码:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
Also the above documentation clearly state that you should not be calling WorkManager.getInstance()
(without the Context
argument):此外,上述文档明确指出您不应调用
WorkManager.getInstance()
(没有Context
参数):
Note: If you call the deprecated no-parameter WorkManager.getInstance() method before WorkManager has been initialized, the method throws an exception.
注意:如果在 WorkManager 初始化之前调用已弃用的无参数 WorkManager.getInstance() 方法,该方法将引发异常。 You should always use the WorkManager.getInstance(Context) method, even if you're not customizing WorkManager.
您应该始终使用 WorkManager.getInstance(Context) 方法,即使您没有自定义 WorkManager。
After looking at the androix/work changelog you will see that a new feature was added in version 2.3.0-beta02 :查看 androix/work 更新日志后,您会看到在2.3.0-beta02版本中添加了一个新功能:
The reason why you have this error after upgrading from version 2.2.0 to 2.3.0.rc1 is because, the android team added a RemoveWorkManagerInitializerDetector that would throw the exception you got in the following pull request at build time.从版本 2.2.0 升级到 2.3.0.rc1 后出现此错误的原因是,android 团队添加了一个RemoveWorkManagerInitializerDetector ,它会在构建时抛出您在以下拉取请求中遇到的异常。
Now about the source code, I suggest you tight the getWorkManager
method to the application directly like below:现在关于源代码,我建议您将
getWorkManager
方法直接与应用程序紧密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);
}
}
And just call App.getWorkManager()
whenever you need to in the app source code只要您需要在应用程序源代码中调用
App.getWorkManager()
You could do something equivalent for your ContentProvider if there is any.如果有的话,您可以为您的 ContentProvider 做一些等效的事情。
PS: Interesting codelabs tutorials exits for java or kotlin PS:有趣的 codelabs 教程退出java或kotlin
WorkManagerInitializer
is used to provide a context to WorkManager
. WorkManagerInitializer
用于提供一个上下文WorkManager
。 This happens because content providers are initialized before the Application
(See this question ).发生这种情况是因为内容提供程序在
Application
之前初始化(请参阅此问题)。 This is the reason you need to provide the context yourself if you do custom initialization.如果您进行自定义初始化,这就是您需要自己提供上下文的原因。 So if you use the custom initialization, you shouldn't need it.
因此,如果您使用自定义初始化,则不需要它。
If you're calling the getWorkManager
method from a content provider then your application instance will be null
.如果您从内容提供者调用
getWorkManager
方法,那么您的应用程序实例将为null
。 To resolve this issue just pass the context as a parameter to the method by calling getContext
inside the content provider:要解决此问题,只需通过在内容提供程序中调用
getContext
将上下文作为参数传递给方法:
public static WorkManager getWorkManager(Context context) {
return WorkManager.getInstance(context);
}
public class MyContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
WorkManager workManager = getWorkManager(getContext());
...
}
...
}
If you are getting this error after updating to WorkManager
2.6.0 or higher, you have to use this snippet in your manifest:如果您在更新到
WorkManager
2.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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.