IllegalStateException: WorkManager уже инициализирован - PullRequest
2 голосов
/ 27 апреля 2019

Имея эти зависимости:

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#initialize(Context, Configuration).


Целью является предотвращение сбоя во время ручной инициализации (для изменения уровня журнала). Как отключить WorkManagerInitializer? Если возможно, я не хочу использовать ключевое слово static.

Ответы [ 4 ]

4 голосов
/ 28 апреля 2019

WorkManager является одноэлементным, его необходимо настроить перед использованием, и вы не можете изменить его конфигурацию без перезапуска приложения.

Второй вызов инициализации вызывает исключение, указывающее, что он не может использовать эту конфигурацию, еслиWorkManager уже инициализирован.Это было дизайнерское решение, принятое во время первых альфа-версий, чтобы избежать молчания сбоев ( 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()
}

Затем, когда вам нужно использовать WorkManager, вместо использования WorkManager#getInstance() (который сейчас устарел), вы должны использовать новый:

WorkManager#getInstance(context)

В этом случае, метод getInstance, проверьте, еслиWorkManager уже инициализирован или нет.Если он еще не инициализирован, он получает конфигурацию с помощью метода getWorkManagerConfiguration(), а затем инициализирует WorkManager.Таким образом, вы больше не звоните WorkManager#initialize(), чтобы полностью избежать проблемы.

Официальная документация была обновлена ​​с этими дополнительными деталями.

Если вы считаете,что WorkManager должен позволять обновлять свою конфигурацию после инициализации, вы должны добавить запрос функции в систему отслеживания проблем библиотеки .

4 голосов
/ 27 апреля 2019

Это как заменить провайдера 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>

Источник: Пользовательская инициализация диспетчера работ (на 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.

И 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;
    }
    ...
}
1 голос
/ 27 апреля 2019

Вы можете контролировать, когда вы позвонили workManager

if(this.workManager == null){
   Configuration config = new Configuration.Builder().build();
   WorkManager.initialize(getApplicationContext(), config);
   this.workManager = WorkManager.getInstance();
}
0 голосов
/ 27 апреля 2019

Если вы хотите инициализировать WorkerManager, вы должны поместить это в onCreate вашего пользовательского класса Application, чтобы он вызывался только один раз.После этого вы можете получить экземпляр, когда вам это нужно, без забот.Не рекомендуется инициализировать Worker Manager.Зачем тебе это?

...