После просмотра объяснения Шона на Android (Google I / O'19) Я пробовал то же самое:
init{
viewModelScope.launch {
Timber.i("coroutine awake")
while (true){
delay(2_000)
Timber.i("another round trip")
}
}
}
К сожалению onCleared
вызывается, когда действие прекращаетсяно не тогда, когда он находится в фоновом режиме («когда мы отходим от действия ...», фон «уходит» imho ^^).
И я получаю следующий вывод:
> ---- Activity in Foreground
> 12:41:10.195 TEST: coroutine awake
> 12:41:12.215 TEST: another round trip
> 12:41:14.231 TEST: another round trip
> 12:41:16.245 TEST: another round trip
> 12:41:18.259 TEST: another round trip
> 12:41:20.270 TEST: another round trip
> ----- Activity in Background (on onCleared not fired)
> 12:41:22.283 TEST: another round trip
> 12:41:24.303 TEST: another round trip
> 12:41:26.320 TEST: another round trip
> 12:41:28.353 TEST: another round trip
> 12:41:30.361 TEST: another round trip
> ----- Activity in Foreground
> 12:41:30.369 TEST: coroutine awake
Как я могу решить это?
1 - Переместить код из init
в suspend fun start()
, вызываемый действием внутри lifecycleScope.launchWhenStarted
?
Я получаю тот же результат.Я думал, что lifecycleScope
отменит свои дочерние сопрограммы, когда он перейдет в фоновый режим, но я получаю тот же вывод Timber с этим подходом.
2 - Измените мой код ViewModel на:
private lateinit var job: Job
suspend fun startEmitting() {
job = viewModelScope.launch {
Timber.i("coroutine awake")
while (true){
delay(2_000)
Timber.i("another round trip")
}
}
}
fun cancelJob(){
if(job.isActive){
job.cancel()
}
}
И в моей Деятельности:
override fun onResume() {
super.onResume()
lifecycleScope.launch {
viewModel.startEmitting()
}
}
override fun onPause() {
super.onPause()
viewModel.cancelJob()
}
Хорошо, это работает, но не является целью viewModelScope
управлять CoroutineScope
для меня?Я ненавижу эту логику отмены работы.
Как лучше всего с этим справиться?