Handler to run task every 5 seconds Kotlin
Asked Answered
C

5

19

I would like to run a certain code every 5 seconds. I am having trouble achieving this with a handler. How can this be done in Kotlin? Here is what I have so far. Also to note, the variable Timer_Preview is a Handler.

My Code

Cipolin answered 24/7, 2017 at 18:42 Comment(3)
you can pass a Callable to your Handler, and sendMessageDelayed recursively.On
Please put code in the question and not link to it because a) Not everybody can get to imgur from work and b) the link might expire and this question will be useless in the future.Koger
Thanks for letting me know!Cipolin
E
28

Since you can't reference a lambda you're currently in, and you can't reference the property you're defining while you're defining the lambda you're assigning to it, the best solution here is an object expression:

val runnableCode = object: Runnable {
    override fun run() {
        handler.postDelayed(this, 5000)
    }
}

Assuming that this property is not a var because you actually want to change it while this self-calling is happening.

Easternmost answered 24/7, 2017 at 18:47 Comment(2)
Thanks that is exactly what I was looking for! Works greatCipolin
Am I right in assuming you can just create a default handler (i.e. val handler:Handler = Handler()) then start it (i.e handler.post(runnableCode)) and it'll run every 5 seconds everything you put in the run block (before handler.postDelayed...)?Alcohol
A
21

Simply Use fixedRateTimer

 fixedRateTimer("timer",false,0,5000){
        [email protected] {
            Toast.makeText(this@MainActivity, "text", Toast.LENGTH_SHORT).show()
        }
    }

Change initial delay by setting another value for the third parameter.

Activism answered 6/1, 2019 at 6:59 Comment(1)
Don't forget to clear up when leaving, though, e.g. on Android: myFixedRateTimer.cancel()Dendritic
K
5

I recommended SingleThread because it is very useful. If you would like to do job for each second, you can set because parameters of it:

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

TimeUnit values are: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS.

Example:

private fun mDoThisJob(){

    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate({
        //TODO: You can write your periodical job here..!

    }, 1, 1, TimeUnit.SECONDS)
}
Kelila answered 4/3, 2020 at 15:30 Comment(0)
P
3

As Kotlin does not yet allow recursive lambdas (see KT-10350), you must use other constructs, such as object expressions as in @zsmb13's answer, or ordinary functions as below

fun StartTimer() {
    Timer_Preview.postDelayed(Runnable { runnable() }, 5000)
}

fun runnable() {
    //Code here

    // Run code again after 5 seconds
    Timer_Preview.postDelayed(Runnable { runnable() }, 5000)
}

However, in your particular case, it looks like you could just call StartTimer() again to re-arm the timer, assuming it doesn't do anything else:

private val RunnableCode = Runnable {
    //Code here

    //Run code again after 5 seconds
    StartTimer()
}
Punster answered 25/7, 2017 at 6:13 Comment(0)
P
0

You can do this with simple functions:

private fun waitToDoSomethingRecursively() {
    handler.postDelayed(::doSomethingRecursively, 5000)
}

private fun doSomethingRecursively () {
    ...
    waitToDoSomethingRecursively()
}
Puss answered 8/10, 2018 at 9:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.