Как мне вызвать сопрограмму и получить ее ссылку на задание, которая будет использоваться в какой-то другой момент, и ожидать завершения? - PullRequest
0 голосов
/ 11 июля 2020

Я настраиваю тестовый сценарий. У меня есть два Activity.

  • SplashActivity
  • HomeActivity

И репозиторий с именем Repository, который вводится в обе модели просмотра этих действий. Это тоже синглтон. Допустим, класс Repository выглядит так:

class Repository {
    suspend fun getData(): List<Data> {
        delay(20000)
        return // the list
    }
}

А теперь формулировка проблемы. Допустим, я хочу вызвать этот метод getData () из модели просмотра SplashActivity и перейти к HomeActivity. И в модели просмотра HomeActivity я хочу прослушать метод, который я вызвал в SplashActivity, и дождаться его завершения.

Итак, вместо того, чтобы getData () снова запустить его метод задержки, я хочу продолжить предыдущий вызов от SplashActivity и дождитесь завершения sh и получите данные.

Как я могу go вперед и сделать это? У меня в голове есть ответ. Но мне это кажется немного взломом. Хотел бы узнать о лучших решениях. Также дай мне знать, неправильно ли я думаю о сопрограммах.

1 Ответ

0 голосов
/ 13 июля 2020

Я бы, вероятно, использовал go CoroutineLiveData, поскольку вы уже используете библиотеку жизненного цикла. Таким образом, ваши данные будут всегда доступны независимо от области действия вызывающего. Выполнение не будет прервано при отмене регистрации наблюдателя.

class Repository {

    val data = liveData {
        emit(getData())
    }

    private suspend fun getData(): List<Data> {
        // work
        return listOf(...)
    }

}

В случае, если вам нужно использовать обратные вызовы с несколькими состояниями (например, необходимо переключаться между «домом» и «входом в систему» ​​в середине выполнения), ваш выбор должен быть каналами или потоками kotlinx. В этом случае вам может пригодиться Судно от teanity .

class Repository {

    val dataVessel = Vessel<MyData>()

    data class MyData(...): Vessel.Sailor
    
    fun requestData() {
        repositoryScope.launch { // scope defined manually for your repo or inherited one
            delay(3000) // do work
            dataVessel.sail(MyData(...)) // sail vessels at will
            delay(3000) // do more work
            dataVessel.sail(MyData(...)) // sail vessels at will
        }
    }
}

val repository = Repository()

viewModelScope.launch { // scope will get cancelled with clearing viewModel
    repository.dock().collect { ... }
}
...