如何在Kotlin延迟后调用一个函数?

Ngu*_*inh 110 android kotlin

作为标题,有没有办法在延迟后调用一个函数(例如1秒)Kotlin

Bog*_*yak 136

还有一个选项可供使用 Handler -> postDelayed

 Handler().postDelayed({
                    //doSomethingHere()
                }, 1000)
Run Code Online (Sandbox Code Playgroud)

  • 请添加它只在Android上可用,因为问题要求一般的kotlin方法(虽然它确实有Android标签) (11认同)
  • 对于Android,最好使用Handler而不是Timer:/sf/ask/1423124881/ (8认同)
  • 从你这边来说,这不具有建设性.因此当用户搜索android标签时可能会认为这是错误的答案. (4认同)
  • 在 Android 中,Handler 已被弃用。有什么替代方案吗? (4认同)
  • @leeCoder 使用:`Handler(Looper.getMainLooper())` 代替。不推荐使用不带 Looper 的 Handler() 调用,但如果您自己指定 Looper 则一切都很好。 (3认同)

Mat*_*aga 92

您可以使用Schedule

inline fun Timer.schedule(
    delay: Long, 
    crossinline action: TimerTask.() -> Unit
): TimerTask (source)
Run Code Online (Sandbox Code Playgroud)

例子(感谢@Nguyen Minh Binh - 在这里找到它: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()
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!超级容易.在这里找到一个例子http://jamie.mccrindle.org/2013/02/exploring-kotlin-standard-library-part-3.html`Timer("SettingUp",false).schedule(500){doSomething()} ` (13认同)
  • 它会编译,如果你添加这两个导入:import java.util.Timer并import import kotlin.concurrent.schedule (7认同)
  • @Matias Elorriaga,对我来说,即使将其添加到导入的新品牌文件中也无法编译,Customizer表示 (3认同)
  • 你不需要把它放在一个文件上,该方法是stdlib的一部分,请按照答案第一行的链接, (3认同)
  • 我原本以为即使导入`kotlin.concurrent.schedule`之后也不会编译,因为Kotlin只是抱怨签名不匹配,但后来我意识到我试图传递一个Int而不是Long。更正后进行编译。 (3认同)
  • 对于那些希望每隔一段时间运行一次的用户:timer.scheduleAtFixedRate(0,inactivityHeartbeat){// ....做东西} (2认同)

Khe*_*raj 49

很多种方法

1.使用Handler课程

Handler().postDelayed({
    TODO("Do something")
    }, 2000)
Run Code Online (Sandbox Code Playgroud)

2.使用Timer课程

Timer().schedule(object : TimerTask() {
    override fun run() {
        TODO("Do something")
    }
}, 2000)
Run Code Online (Sandbox Code Playgroud)

Timer().schedule(timerTask {
    TODO("Do something")
}, 2000)
Run Code Online (Sandbox Code Playgroud)

最短

Timer().schedule(2000) {
    TODO("Do something")
}
Run Code Online (Sandbox Code Playgroud)

3.使用Executors课程

Executors.newSingleThreadScheduledExecutor().schedule({
    TODO("Do something")
}, 2, TimeUnit.SECONDS)
Run Code Online (Sandbox Code Playgroud)

  • 只是为了跟进有关 Handler().postDelayed 是最佳解决方案的评论...现在已弃用(至少在 Android 中)并建议 Executors,所以至少对于 Android 我会说这是“最佳解决方案”(尽管定时器也简单明了) (4认同)
  • 您认为最好的解决方案是什么? (2认同)
  • 可能是第一个使用处理程序的。请参阅/sf/answers/2823774131/ (2认同)

小智 30

您必须导入以下两个库:

import java.util.*
import kotlin.concurrent.schedule
Run Code Online (Sandbox Code Playgroud)

然后以这种方式使用它:

Timer().schedule(10000){
    //do something
}
Run Code Online (Sandbox Code Playgroud)


dwb*_*ito 20

如果您使用的是更新的 Android API,则 Handler 空构造函数已被弃用,您应该包含一个 Looper。你可以很容易地得到一个通过Looper.getMainLooper()

    Handler(Looper.getMainLooper()).postDelayed({
        //Your code
    }, 2000) //millis
Run Code Online (Sandbox Code Playgroud)


Jon*_*lms 18

您可以launch使用协程,delay然后调用该函数:

 /*GlobalScope.*/launch {
   delay(1000)
   yourFn()
 }
Run Code Online (Sandbox Code Playgroud)

如果你不在类或对象之前GlobalScope让coroutine在那里运行,否则建议CoroutineScope在周围的类中实现它,这允许在必要时取消与该作用域相关的所有协同程序.


var*_*tty 17

val timer = Timer()
timer.schedule(timerTask { nextScreen() }, 3000)
Run Code Online (Sandbox Code Playgroud)

  • 我想你是。“ Timer.schedule()”期望“ TimerTask”作为其第一个参数。`kotlin.concurrent.timerTask()`将给定的lambda包装在`TimerTask`实例中。看到这里:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/timer-task.html (2认同)

Zee*_*ro0 9

一个简单的例子,显示3秒后的祝酒词:

fun onBtnClick() {
    val handler = Handler()
    handler.postDelayed({ showToast() }, 3000)
}

fun showToast(){
    Toast.makeText(context, "Its toast!", Toast.LENGTH_SHORT).show()
}
Run Code Online (Sandbox Code Playgroud)


Ogu*_*han 6

如果您正在寻找通用用法,这是我的建议:

创建一个名为的类Run

class Run {
    companion object {
        fun after(delay: Long, process: () -> Unit) {
            Handler().postDelayed({
                process()
            }, delay)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

Run.after(1000, {
    // print something useful etc.
})
Run Code Online (Sandbox Code Playgroud)


And*_*rew 6

如果您在具有 viewModel 范围的片段中,您可以使用 Kotlin 协程:

    myViewModel.viewModelScope.launch {
        delay(2000)
        // DoSomething()
    }
Run Code Online (Sandbox Code Playgroud)