#android #kotlin-coroutines #android-livedata
Вопрос:
Мне нужна ваша помощь, есть livedata, которая возвращает логическое значение, которое постоянно меняется. Мне нужно, чтобы при выполнении true сопрограмма выполнялась (есть просто имитация процентов загрузки от 0 до 100%), соответственно, false отменяет ее и так далее по кругу.
если он возвращает значение true, запустите сопрограмму, в противном случае она будет отменена
graphicOverlay.onSuccess.observe(viewLifecycleOwner, {
auraImageView.isInvisible = it != true
noteScanFaceView.isVisible = it == false
if (!isFaceDetected) {
if (it) {
buttonChangeCameraSelector.isVisible = false
llScanning.isVisible = true
viewLifecycleOwner.lifecycleScope.launch {counter()}
isFaceDetected = true
} else {
viewLifecycleOwner.lifecycleScope.cancel()
}
}
})
это счетчик
private suspend fun counter() = viewLifecycleOwner.lifecycleScope.launch {
val job = launch {
while (progressStatus < 100) {
progressStatus = 1
delay(50)
handler.post {
textViewPercent.text = "$progressStatus"
}
}
}
job.join()
fragmentSendDataListener.onSendResultsModel(resultSendData)
requireActivity().runOnUiThread {
llToolbar.isVisible = false
}
}
Ответ №1:
Вы должны переопределить свой счетчик, вы запускаете сопрограмму, которая запускает сопрограмму, которую можно превратить всего в одну запущенную сопрограмму. И для того, чтобы отменить сопрограмму, вы должны сделать ее совместимой с возможностью отмены.
private suspend fun counter() {
while (coroutineContext.isActive amp;amp; progressStatus < 100) {
progressStatus = 1
delay(50)
handler.post {
textViewPercent.text = "$progressStatus"
}
}
fragmentSendDataListener.onSendResultsModel(resultSendData)
requireActivity().runOnUiThread {
llToolbar.isVisible = false
}
}
Поскольку запуск возвращает задание, сохраните ссылку на него и при необходимости переопределите/отмените его
.
private var counterJob: Job? = null
graphicOverlay.onSuccess.observe(viewLifecycleOwner, {
auraImageView.isInvisible = it != true
noteScanFaceView.isVisible = it == false
if (!isFaceDetected) {
if (it) {
buttonChangeCameraSelector.isVisible = false
llScanning.isVisible = true
counterJob = viewLifecycleOwner.lifecycleScope.launch {counter()}
isFaceDetected = true
} else counterJob?.cancel()
}
})
Комментарии:
1. Спасибо, я уже немного повозился.
Ответ №2:
запуск возвращает значение a Job
, которое вы можете отменить вместо всей области действия сопрограммы.
Поэтому я бы сделал что-то следующее:
- Сохраните ссылку на свою работу счетчика:
private var counterJob: Job? = null
- Обновляйте его по мере необходимости:
counterJob = launch { counter() }
- Отмените его, когда это необходимо:
counterJob?.cancel()
Комментарии:
1. Спасибо за ответ, но в моем случае это не работает. Сопрограмма не отменяется, если получено значение false. Что я делаю не так?
2. В этом случае ссылка не равна нулю, но счетчик продолжает идти