Java IllegalStateException:工作管理器已初始化

Java IllegalStateException:工作管理器已初始化,java,android,illegalstateexception,androidx,android-workmanager,Java,Android,Illegalstateexception,Androidx,Android Workmanager,具有这些依赖关系: dependencies { implementation "androidx.work:work-runtime:2.0.1" androidTestImplementation "androidx.work:work-testing:2.0.1" } 第二次运行此代码时: Configuration config = new Configuration.Builder().build(); WorkManager.initialize(getApplic

具有这些依赖关系:

dependencies {
    implementation "androidx.work:work-runtime:2.0.1"
    androidTestImplementation "androidx.work:work-testing:2.0.1"
}
第二次运行此代码时:

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

this.workManager = WorkManager.getInstance();
我收到以下错误消息:

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.
它也会在本机端抛出一个分段错误:

A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR),
fault addr 0x878 in tid 10892 (ova.workmanager),
pid 10892 (ova.workmanager)
这将是
WorkManager#初始化(上下文、配置)
的关键



其目的是防止在手动初始化期间发生崩溃(以更改日志级别)。如何禁用
工作管理器初始化程序
?如果可能,我不想使用
static
关键字。

您可以控制何时调用workManager

if(this.workManager == null){
   Configuration config = new Configuration.Builder().build();
   WorkManager.initialize(getApplicationContext(), config);
   this.workManager = WorkManager.getInstance();
}

这是如何替换provider
androidx.work.impl.WorkManagerInitializer

<application>
    ...

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

    <!-- register custom provider -->
    <provider
        android:name=".CustomWorkManagerInitializer"
        android:authorities="${applicationId}.WorkManagerInit"/>

</application>
以及在
src/debug/Manifest.xml
中注册的
ContentProvider

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

如果要初始化WorkerManager,必须将其放入自定义应用程序类的onCreate中,因此只能调用一次。之后,您只能在需要时无需担心地获得实例。不建议初始化工作管理器。为什么需要它?

WorkManager是一个单机版,需要在使用前对其进行配置,如果不重新启动应用程序,则无法更改其配置

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

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

使用新的按需配置,您必须向应用程序添加
配置.Provider
接口,如下所示:

class MyApplication : Application(), Configuration.Provider {

   override fun getWorkManagerConfiguration(): Configuration =
       // provide custom configuration
       Configuration.Builder()
               .setMinimumLoggingLevel(android.util.Log.INFO)
               .setWorkerFactory(MyWorkerFactory())
               .build()
}
然后,当您需要使用WorkManager时,您应该使用新的:

WorkManager#getInstance(context)
在本例中,使用getInstance方法,检查WorkManager是否已初始化它。如果尚未初始化,它将使用
getWorkManagerConfiguration()
方法检索配置,然后初始化WorkManager。这样,您就不再调用
WorkManager#initialize()
,完全避免了这个问题

已使用这些附加详细信息更新


如果您认为WorkManager应允许在初始化后更新其配置,则应向添加一个功能请求。

这仍将第二次(或更频繁地)调用
initialize
。WorkManager==null将始终计算为
true
。您的问题缺少很多详细信息。是否确实要多次初始化工作进程?第一次初始化是如何工作的,您是否按照文档正确初始化了它?你在哪里初始化了worker,哪个类,以及这个类的生命周期中的确切位置?@ronginat与其他问题相比,它非常详细。你们的问题可能都已经被这个问题回答了。当然,我不想初始化它两次,也不需要任何工人来产生崩溃。到目前为止,您回答了我的第一个问题,因此我知道您不想做一些不可能的事情(您不能多次初始化工人)。如果您的代码运行多次并试图初始化辅助程序,那么它可能不是正确的位置。这就是为什么我问你在哪里初始化工人,以及在清单没有任何更改的情况下第一次是如何工作的(我猜你在写这个问题时没有更改答案中所写的清单)。@rongina确切地说,它发生在安排一个作业,然后再安排另一个作业时;在尝试取消作业时也是如此。它的棘手之处在于,
.getInstance()
是一个
静态方法,而不是实例方法。这个答案只是我根据错误消息中的建议找到的一种方法;仍然需要对此进行测试(博客文章只是一个类似的情况)。然后最安全的方法是只在
应用程序#onCreate
中初始化它一次,如中所建议的(就在代码块下面)。在那之后,在代码中的任何地方自由使用静态的
getInstance
,因为
WorkManager
已经初始化。它是一个单例是实际的问题,而
ContentProvider.onCreate()
应用程序。onCreate()
似乎只被调用一次,因此只能在那里运行。在
活动中,当检查
savedInstanceState!=null
。不需要稍后更新配置,但它可以使用一种方法来告知初始化状态。。。else once无法初始化OnDemand,而只能初始化OnCreate。如果没有这种方法,调试/发布版本可能是切换提供程序的唯一方法。请告诉我有关新的按需语法的其他详细信息是否涵盖了您的问题。在这种情况下,您永远不会调用initialize,必要时getInstance(上下文)负责初始化WorkManager
WorkManager#getInstance(context)