Home > OS >  Timer based on Handler stops, Android, Kotlin
Timer based on Handler stops, Android, Kotlin

Time:05-11

I use Handler for creating a timer in a Widget. I use the recommended constructor, i.e. passing a Looper to it.

    private val updateHandler = Handler(Looper.getMainLooper())

    @RequiresApi(Build.VERSION_CODES.Q)
    private val runnable = Runnable {
        updateDisplay()
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    private fun updateDisplay () {
        updateHandler?.postDelayed(runnable, TIMER_MS)
        // some other code
    }

The TIMER MS is set to 3000 ms. The timer runs fine for a while and execute the given code. However after a random time elapsed the timer stops working and no more execution of the given code happens.

Please advise what the problem could be ond how to fix it. Alternatively, can I use some other timer? (The timer should go off every few second - this is the reason why I use Handler)

Thank you for any advice in advance

CodePudding user response:

You could always try using a Coroutine for something like this:

class TimedRepeater(var delayMs: Long,
                    var worker: (() -> Unit)) {
    private var timerJob: Job? = null
    
    suspend fun start() {
        if (timerJob != null) throw IllegalStateException()
        timerJob = launch {
            while(isActive) {
                delay(delayMs)
                worker()
            }
        }
    }
    suspend fun stop() {
        if (timerJob == null) return
        timerJob.cancelAndJoin()
        timerJob = null
    }
}

suspend fun myStuff() {
    val timer = Timer(1000) {
        // Do my work
    }
    timer.start()
    // Some time later
    timer.stop()
}

I haven't tested the above, but it should work well enough.

CodePudding user response:

You can use CountDownTimer from Android framework to achieve the same. It internally uses Handler for timer

val timer = object: CountDownTimer(1000,1000){
    override fun onTick(millisUntilFinished: Long) {
         
    }

    override fun onFinish() {
    }
}
timer.start()
  • Related