WorkManager - 当我们同时使用默认初始化和自定义初始化时,我们是否应该删除默认初始化程序?
WorkManager - Should we remove the default initializer, when we use both Default initialization and Custom initialization?
当我将 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 中没有出现这样的错误,因为 "On-Demand Initialization" 是从 2.1.0 开始引入的。
我不确定在我的 AndroidManifest.xml
中包含以下内容是否正确。
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
目前以下是我的Application
class.
我的应用程序class
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);
}
}
当 Application
class 为空时,"Default initialization" (WorkManager.getInstance()
) 似乎也很少被执行。
我可以通过包含以下 provider
轻松消除 APK 导出过程中的错误。但是,这样做对吗?
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
WorkManagerInitializer
用于为 WorkManager
提供上下文。发生这种情况是因为内容提供程序在 Application
之前初始化(参见 this question)。如果您进行自定义初始化,这就是您需要自己提供上下文的原因。所以如果你使用自定义初始化,你应该不需要它。
如果您从 content provider 调用 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());
...
}
...
}
我们在 WorkManager 2.3.0-*
中引入了这个 lint 规则。我们试图用这个 Lint 规则解决的问题是,如果你同时拥有 WorkManagerInitializer
ContentProvider
和你的 Application
子类型实现 Configuration.Provider
(用于按需初始化) - ContentProvider
将 始终 优先。
这可能出乎意料,尤其是当您有额外的 Configuration
时, 不会 生效,因为 ContentProvider
始终 使用默认配置。
您真正需要做的就是删除默认提供程序。这样初始化就不再是急切的,而是按需的。
是的,如果您想使用 on-demand initialization,您需要删除默认的工作管理器初始值设定项,因此请在您的清单中保留以下代码:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
此外,上述文档明确指出您不应该调用 WorkManager.getInstance()
(没有 Context
参数):
Note: If you call the deprecated no-parameter WorkManager.getInstance() method before WorkManager has been initialized, the method throws an exception. You should always use the WorkManager.getInstance(Context) method, even if you're not customizing 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 that would throw the exception you got in the following pull request。
现在关于源代码,我建议您直接将 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 做一些等效的事情。
如果您在更新到 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>
当我将 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 中没有出现这样的错误,因为 "On-Demand Initialization" 是从 2.1.0 开始引入的。
我不确定在我的 AndroidManifest.xml
中包含以下内容是否正确。
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
目前以下是我的Application
class.
我的应用程序class
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);
}
}
当 Application
class 为空时,"Default initialization" (WorkManager.getInstance()
) 似乎也很少被执行。
我可以通过包含以下 provider
轻松消除 APK 导出过程中的错误。但是,这样做对吗?
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
WorkManagerInitializer
用于为 WorkManager
提供上下文。发生这种情况是因为内容提供程序在 Application
之前初始化(参见 this question)。如果您进行自定义初始化,这就是您需要自己提供上下文的原因。所以如果你使用自定义初始化,你应该不需要它。
如果您从 content provider 调用 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());
...
}
...
}
我们在 WorkManager 2.3.0-*
中引入了这个 lint 规则。我们试图用这个 Lint 规则解决的问题是,如果你同时拥有 WorkManagerInitializer
ContentProvider
和你的 Application
子类型实现 Configuration.Provider
(用于按需初始化) - ContentProvider
将 始终 优先。
这可能出乎意料,尤其是当您有额外的 Configuration
时, 不会 生效,因为 ContentProvider
始终 使用默认配置。
您真正需要做的就是删除默认提供程序。这样初始化就不再是急切的,而是按需的。
是的,如果您想使用 on-demand initialization,您需要删除默认的工作管理器初始值设定项,因此请在您的清单中保留以下代码:
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
此外,上述文档明确指出您不应该调用 WorkManager.getInstance()
(没有 Context
参数):
Note: If you call the deprecated no-parameter WorkManager.getInstance() method before WorkManager has been initialized, the method throws an exception. You should always use the WorkManager.getInstance(Context) method, even if you're not customizing 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 that would throw the exception you got in the following pull request。
现在关于源代码,我建议您直接将 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 做一些等效的事情。
如果您在更新到 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>