Непрерывное получение из сопрограммного канала в рамках действия - PullRequest
0 голосов
/ 01 апреля 2020

Я пишу приложение Android, используя сопрограммы Kotlin в Activity. У меня есть следующее объявление о канале, который я могу использовать для получения потока уведомлений, и хочу понять, как лучше всего выполнить связанные операции с главным диспетчером (UI):

    private var stateNotifications: Channel<Notification>? = null

I В настоящее время мы создали Handler, чтобы можно было опрашивать stateNotifications. Его настройка выглядит следующим образом:

            stateNotificationHandler.postDelayed(
                handleStateNotifications,
                100L
            )

с handleStateNotifications объявлено что-то вроде:

    private val handleStateNotifications: Runnable = Runnable {
        run {
            val x = when (stateNotifications?.poll()) {
                is ...
            } // FIXME: UPDATE UI
            stateNotificationHandler.postDelayed(
                handleStateNotifications,
                handleStateNotificationsInterval
            )
        }
    }

Это похоже на работу. Тем не менее, я думаю, что должен быть способ получить stateNotifications на диспетчере по умолчанию, а затем распределить события в потоке пользовательского интерфейса. Я думал что-то вроде этого:

            launch {
                flow<Notification?> {
                    emit(notifications.receive())
                }.onEach { perhaps-invoke-a-handler-to-update-ui }.collect()
            }

... но пока нет сигар.

1 Ответ

0 голосов
/ 02 апреля 2020

После хорошего ночного сна, я понял, что мне нужно постоянно принимать в oop, используя хороший и отзывчивый подход, основанный на flow, например:

        job = defaultScope.launch() {
            val notifications = Channel<Handwashing.Notification>()

            launch {
                flow<Notification?> {
                    while (true) {
                        emit(notifications.receive())
                    }
                }.onEach {
                    stateNotificationHandler.postDelayed( {
                        // Do some UI thing
                    },  0)
                }.collect()
            }

            // Push notifications to the notifications channel.
        }
    }

Обратите внимание, что внешний job важно, чтобы отменить все сопрограммы здесь позже, когда вам нужно привести в порядок.

...