In my code, I have a time-out functionality and I want to use a countdown timer but after a lot of research, I couldn't find similar functionality as a countdown timer in Kotlin coroutine (able to start, cancel and catch finish callback). Then I decided to use GlobalScope.launch
. I know this is a bad solution but my code is working perfectly.
Here is my code
viewModelScope.launch {
val timer = object: CountDownTimer(Constants.PAYMENT_TIMER, 1000) {
override fun onTick(millisUntilFinished: Long) {}
override fun onFinish() {
GlobalScope.launch {
_eventFlow.emit(UIPaymentEvent.NavigateToBack)
}
}
}
timer.start()
collectPaymentIntentUseCase.invoke(currentPaymentIntent!!).onEach { result ->
when (result) {
is Resource.Success -> {
timer.cancel()
if (result.data?.exception == null) {
My question is how can find a 100% similar function to avoid using GlobalScope but be able to use the countdown timer (start, cancel,onComplete callback)?
Note: I am using GlobalScope.lanch to be able to emit UIPaymentEvent.NavigateToBack event to my view
CodePudding user response:
Your question is somewhat unclear, please try to add more details what actually are you trying to achieve and what is the error you are facing.
CodePudding user response:
You don't need a CountDownTimer
here. Just use the delay()
suspend function.
viewModelScope.launch {
val job = launch {
delay(Constants.PAYMENT_TIMER) // Wait for timeout
_eventFlow.emit(UIPaymentEvent.NavigateToBack)
}
collectPaymentIntentUseCase.invoke(currentPaymentIntent!!).onEach { result ->
when (result) {
is Resource.Success -> {
job.cancel() // Cancel the timer
if (result.data?.exception == null) {
CodePudding user response:
You can use callbackFlow
for listen your timer. I just code this editor. I hope it will be helpful.
fun timerFlow() = callbackFlow<UIPaymentEvent> {
val timer = object : CountDownTimer(10, 1000) {
override fun onTick(millisUntilFinished: Long) {}
override fun onFinish() {
CoroutineScope().launch {
_eventFlow.emit(UIPaymentEvent.NavigateToBack)
}
}
}
timer.start()
awaitClose()
}