Как распоряжаться Rx в WorkManager? - PullRequest
0 голосов
/ 16 октября 2018

Я реализовал AlarmManager для отправки уведомлений, когда пользователь добавляет срок выполнения к Задаче.Тем не менее, когда пользователь выключает устройство, все тревоги теряются.Теперь я обновляю BroadcastReceiver, чтобы получить android.intent.action.BOOT_COMPLETED и переназначаю все аварийные сигналы, установленные для каждой задачи.

Моя первая попытка состояла в том, чтобы получить Rx Single со всеми задачами, срок выполнения которых составляетвыше текущего времени внутри BroadcastReceiver, затем перепланируйте все аварийные сигналы.Проблема в том, что я не могу утилизировать Observable, если у BroadcastReceiver нет жизненного цикла.Кроме того, кажется, что это не очень хороший подход .

Во время моих исследований IntentService был хорошим решением для этого случая, но я вхожу в новый WorkManager библиотека и OneTimeWorkRequest выглядит как хорошее и простое решение.

Worker вызывается и выполняется правильно, но я не могу утилизировать Observable, потому что метод onStoppedникогда не вызывается.

Вот реализация, основанная на этом фрагменте :

class TaskAlarmWorker(context: Context, params: WorkerParameters) :
    Worker(context, params), KoinComponent {

    private val daoRepository: DaoRepository by inject()

    private val compositeDisposable = CompositeDisposable()

    override fun doWork(): Result {
        Timber.d("doWork")

        val result = LinkedBlockingQueue<Result>()

        val disposable =
            daoRepository.getTaskDao().getAllTasks().applySchedulers().subscribe(
            { result.put(Result.SUCCESS) },
            { result.put(Result.FAILURE) }
        )

        compositeDisposable.add(disposable)

        return try {
            result.take()
        } catch (e: InterruptedException) {
            Result.RETRY
        }
    }

    override fun onStopped(cancelled: Boolean) {
        Timber.d("onStopped")
        compositeDisposable.clear()
    }
}
  • Является ли WorkManager хорошим решением для этого случая?
  • Можно ли правильно расположить Observable?

Ответы [ 2 ]

0 голосов
/ 18 июля 2019
  • Да WorkManager - хорошее решение (даже может быть лучшим)
  • Вы должны использовать RxWorker вместо Worker.Вот пример:

    1. Для его реализации.добавьте androidx.work: work-rxjava2: $ work_version в файл build.gradle в качестве зависимости.

    2. Расширьте свой класс из класса RxWorker, затем переопределите *Функция 1020 *.

class TaskAlarmWorker(context: Context, params: WorkerParameters) :
    RxWorker(context, params), KoinComponent {

    private val daoRepository: DaoRepository by inject()  

    override fun createWork(): Single<Result> {
        Timber.d("doRxWork")

     return daoRepository.getTaskDao().getAllTasks()
                .doOnSuccess { /* process result somehow */ }
                .map { Result.success() }
                .onErrorReturn { Result.failure() }          

    }

}

Важные замечания о RxWorker :

  • CreateWork() метод вызывается в главном потоке, но возвращаемый single подписывается в фоновом потоке.
  • Вам не нужно беспокоиться об удалении Observer, поскольку RxWorker автоматически удалит его после остановки работы.
  • И возвращение Single со значением Result.failure () и одиночное с ошибкой приведут к тому, что работник перейдет в состояние отказа.
  • Вы можете переопределить функцию onStopped, чтобы сделатьподробнее.

Подробнее:

0 голосов
/ 17 октября 2018

Вы можете очистить его в методе onStoped(), затем compositeDisposable.dispose();

Затем вызвать super.onStoped()

...