IllegalStateException:WorkManager已经初始化

Mar*_*ler 4 java android illegalstateexception android-workmanager androidx

具有以下依赖性:

dependencies {
    implementation "androidx.work:work-runtime:2.0.1"
    androidTestImplementation "androidx.work:work-testing:2.0.1"
}
Run Code Online (Sandbox Code Playgroud)

当第二次运行此代码时:

Configuration config = new Configuration.Builder().build();
WorkManager.initialize(getApplicationContext(), config);

this.workManager = WorkManager.getInstance();
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息:

java.lang.IllegalStateException: WorkManager is already initialized.
Did you try to initialize it manually without disabling WorkManagerInitializer?
See WorkManager#initialize(Context, Configuration) or the class level Javadoc for more information.
Run Code Online (Sandbox Code Playgroud)

并且还会在本机端引发分段错误:

A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR),
fault addr 0x878 in tid 10892 (ova.workmanager),
pid 10892 (ova.workmanager)
Run Code Online (Sandbox Code Playgroud)

这将是文档WorkManager#initialize(Context, Configuration)


目的是防止在手动初始化期间崩溃(以更改日志级别)。如何禁用WorkManagerInitializer?如果可能的话,我不想使用static关键字。

And*_* D. 19

WorkManager 2.6 开始,App Startup在 WorkManager 内部使用。要提供自定义初始化程序,您需要删除 androidx.startup 节点。

如果您不在应用程序中使用应用程序启动,则可以将其完全删除。

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove">
</provider>
Run Code Online (Sandbox Code Playgroud)

否则,仅删除 WorkManagerInitializer 节点。

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

    <!-- If you are using androidx.startup to initialize other components -->
    <meta-data
        android:name="androidx.work.WorkManagerInitializer"
        android:value="androidx.startup"
        tools:node="remove" />
</provider>
Run Code Online (Sandbox Code Playgroud)

当使用低于 2.6 的 WorkManager 版本时,请删除 workmanager-init:

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


Mar*_*ler 5

这是替代提供商的方法androidx.work.impl.WorkManagerInitializer

<application>
    ...

    <!-- disable default provider -->
    <provider
        android:name="androidx.work.impl.WorkManagerInitializer"
        android:authorities="com.packagename.workmanager-init"
        android:exported="false"
        android:enabled="false"/>

    <!-- register custom provider -->
    <provider
        android:name=".CustomWorkManagerInitializer"
        android:authorities="com.packagename.WorkManagerInit"/>

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

来源:Custom Work Manager初始化(在Kotlin中)。


除非注册其他提供者,否则将给出:

java.lang.IllegalStateException: WorkManager is not initialized properly. The most
likely cause is that you disabled WorkManagerInitializer in your manifest but forgot
to call WorkManager#initialize in your Application#onCreate or a ContentProvider.
Run Code Online (Sandbox Code Playgroud)

并在中ContentProvider注册src/debug/Manifest.xml

public class WorkManagerInit extends ContentProvider {

    @Override
    public boolean onCreate() {
        if(getContext() != null) {
            Configuration config = new Configuration.Builder().build();
            WorkManager.initialize(getContext().getApplicationContext(), config);
        }
        return true;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)


pfm*_*ggi 5

WorkManager是单例,需要在使用前进行配置,并且您必须重新启动应用程序才能更改其配置。

如果初始化了WorkManager,则第二次调用initialize会引发异常,表明它无法使用该配置。这是在最初的Alpha版本中做出的一项设计决策,以避免无提示地失败(workmanager-1.0.0-alpha11)。

WorkManager v2.1添加了一种按需方式来初始化库,因此您可以将实际的初始化从应用程序的热启动序列中移出。但是,您仍然具有只能配置一次WorkManager的约束。

使用新的按需配置,您必须Configuration.Provider像下面这样向应用程序添加接口:

class MyApplication : Application(), Configuration.Provider {

   override fun getWorkManagerConfiguration(): Configuration =
       // provide custom configuration
       Configuration.Builder()
               .setMinimumLoggingLevel(android.util.Log.INFO)
               .setWorkerFactory(MyWorkerFactory())
               .build()
}
Run Code Online (Sandbox Code Playgroud)

然后,当您需要使用WorkManager时,而不是使用WorkManager#getInstance()(现已弃用),则应使用新的:

WorkManager#getInstance(context)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,使用getInstance方法检查WorkManager是否已初始化。如果尚未初始化,它将使用getWorkManagerConfiguration()方法检索配置,然后初始化WorkManager。这样,您就不再可以WorkManager#initialize()完全避免问题了。

官方文档已经更新了这些额外的细节。

如果您认为WorkManager在初始化后应允许更新其配置,则应向库的问题跟踪器中添加功能请求。