【发布时间】:2017-09-06 23:59:45
【问题描述】:
如题,KotlinKotlin中延迟(例如1秒)后有什么方法可以调用函数吗?
【问题讨论】:
如题,KotlinKotlin中延迟(例如1秒)后有什么方法可以调用函数吗?
【问题讨论】:
您可以使用Schedule
inline fun Timer.schedule(
delay: Long,
crossinline action: TimerTask.() -> Unit
): TimerTask (source)
示例(感谢@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()
}
【讨论】:
Timer("SettingUp", false).schedule(500) { doSomething() }
kotlin.concurrent.schedule 之后也无法编译,因为 Kotlin 只是抱怨签名不匹配,但后来我意识到我试图传递一个 Int 而不是 Long。它在更正后编译。
还有一个选项可以使用Handler -> postDelayed
Handler().postDelayed({
//doSomethingHere()
}, 1000)
【讨论】:
val timer = Timer()
timer.schedule(timerTask { nextScreen() }, 3000)
【讨论】:
Timer.schedule() 期望 TimerTask 作为它的第一个参数。 kotlin.concurrent.timerTask() 将给定的 lambda 包装在 TimerTask 实例中。见这里:kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/…
Timer 对象不会被多次使用,例如Timer().schedule(timerTask { ... }, 3000),则可以将给定示例压缩为一行。还有一个更适合 Kotlin 的选项;见 jonguer 的回答。
3 秒后显示敬酒的简单示例:
fun onBtnClick() {
val handler = Handler()
handler.postDelayed({ showToast() }, 3000)
}
fun showToast(){
Toast.makeText(context, "Its toast!", Toast.LENGTH_SHORT).show()
}
【讨论】:
你必须导入以下两个库:
import java.util.*
import kotlin.concurrent.schedule
然后以这种方式使用它:
Timer().schedule(10000){
//do something
}
【讨论】:
如果您正在寻找通用用法,这是我的建议:
创建一个名为Run的类:
class Run {
companion object {
fun after(delay: Long, process: () -> Unit) {
Handler().postDelayed({
process()
}, delay)
}
}
}
并像这样使用:
Run.after(1000, {
// print something useful etc.
})
【讨论】:
Run.after(1000) { toRun() }。我说的对吗
你可以launch一个协程,delay它然后调用函数:
/*GlobalScope.*/launch {
delay(1000)
yourFn()
}
如果您在一个类或对象之外,请在前面添加GlobalScope 让协程在那里运行,否则建议在周围的类中实现CoroutineScope,这样可以在必要时取消与该范围关联的所有协程.
【讨论】:
Handler类Handler().postDelayed({
TODO("Do something")
}, 2000)
Timer 类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 类Executors.newSingleThreadScheduledExecutor().schedule({
TODO("Do something")
}, 2, TimeUnit.SECONDS)
【讨论】:
我推荐使用SingleThread,因为你不必在使用后杀死它。此外,“stop()”方法在 Kotlin 语言中已被弃用。
private fun mDoThisJob(){
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate({
//TODO: You can write your periodical job here..!
}, 1, 1, TimeUnit.SECONDS)
}
此外,您可以将它用于定期工作。这是非常有用的。如果你想每秒做一个工作,你可以设置它的参数:
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
TimeUnit 值是:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS、MINUTES、HOURS、DAYS。
【讨论】:
如果您使用的是较新的 Android API,则不推荐使用 Handler 空构造函数,您应该包含 Looper。您可以通过Looper.getMainLooper()轻松获得。
Handler(Looper.getMainLooper()).postDelayed({
//Your code
}, 2000) //millis
【讨论】:
如果您在具有 viewModel 范围的片段中,则可以使用 Kotlin 协程:
myViewModel.viewModelScope.launch {
delay(2000)
// DoSomething()
}
【讨论】:
我建议使用 kotlin 协程,如果你想取消它。它简单而重量轻。
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()
【讨论】: