How to call a function after delay in Kotlin?
AndroidKotlinAndroid Problem Overview
As the title, is there any way to call a function after delay (1 second for example) in Kotlin
?
Android Solutions
Solution 1 - Android
There is also an option to use Handler -> postDelayed
Handler().postDelayed({
//doSomethingHere()
}, 1000)
Solution 2 - Android
You can use Schedule
inline fun Timer.schedule(
delay: Long,
crossinline action: TimerTask.() -> Unit
): TimerTask (source)
example (thanks @Nguyen Minh Binh - found it here: http://jamie.mccrindle.org/2013/02/exploring-kotlin-standard-library-part-3.html)
import java.util.Timer
import kotlin.concurrent.schedule
Timer("SettingUp", false).schedule(500) {
doSomething()
}
Solution 3 - Android
Many Ways
Handler
class
1. Using Handler().postDelayed({
TODO("Do something")
}, 2000)
Timer
class
2. Using Timer().schedule(object : TimerTask() {
override fun run() {
TODO("Do something")
}
}, 2000)
// Shorter
Timer().schedule(timerTask {
TODO("Do something")
}, 2000)
// Shortest
Timer().schedule(2000) {
TODO("Do something")
}
Executors
class
3. Using Executors.newSingleThreadScheduledExecutor().schedule({
TODO("Do something")
}, 2, TimeUnit.SECONDS)
Solution 4 - Android
You could launch
a coroutine, delay
it and then call the function:
/*GlobalScope.*/launch {
delay(1000)
yourFn()
}
If you are outside of a class or object prepend GlobalScope
to let the coroutine run there, otherwise it is recommended to implement the CoroutineScope
in the surrounding class, which allows to cancel all coroutines associated to that scope if necessary.
Solution 5 - Android
You have to import the following two libraries:
import java.util.*
import kotlin.concurrent.schedule
and after that use it in this way:
Timer().schedule(10000){
//do something
}
Solution 6 - Android
val timer = Timer()
timer.schedule(timerTask { nextScreen() }, 3000)
Solution 7 - Android
If you are in a fragment with viewModel scope you can use Kotlin coroutines:
myViewModel.viewModelScope.launch {
delay(2000)
// DoSomething()
}
Solution 8 - Android
A simple example to show a toast after 3 seconds :
fun onBtnClick() {
val handler = Handler()
handler.postDelayed({ showToast() }, 3000)
}
fun showToast(){
Toast.makeText(context, "Its toast!", Toast.LENGTH_SHORT).show()
}
Solution 9 - Android
If you're using more recent Android APIs the Handler empty constructor has been deprecated and you should include a Looper. You can easily get one through Looper.getMainLooper()
.
Handler(Looper.getMainLooper()).postDelayed({
//Your code
}, 2000) //millis
Solution 10 - Android
If you are looking for generic usage, here is my suggestion:
Create a class named as Run
:
class Run {
companion object {
fun after(delay: Long, process: () -> Unit) {
Handler().postDelayed({
process()
}, delay)
}
}
}
And use like this:
Run.after(1000, {
// print something useful etc.
})
Solution 11 - Android
i suggest to use kotlin coroutine and if you want to cancel it. its simple and light weight.
fun repeatFun(): Job {
return coroutineScope.launch {
while(isActive) {
//do your work here
delay(1000)
}
}
}
//start the loop
val repeatFun = repeatRequest()
//Cancel the loop
repeatFun.cancel()
Solution 12 - Android
I recommended using SingleThread because you do not have to kill it after using. Also, "stop()" method is deprecated in Kotlin language.
private fun mDoThisJob(){
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate({
//TODO: You can write your periodical job here..!
}, 1, 1, TimeUnit.SECONDS)
}
Moreover, you can use it for periodical job. 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.