Kotlin延迟后如何调用函数?
Posted
技术标签:
【中文标题】Kotlin延迟后如何调用函数?【英文标题】:How to call a function after delay in Kotlin? 【发布时间】:2017-09-06 23:59:45 【问题描述】:如题,Kotlin
Kotlin
中延迟(例如1秒)后有什么方法可以调用函数吗?
【问题讨论】:
【参考方案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()
【讨论】:
谢谢!超级容易。在这里找到了一个例子jamie.mccrindle.org/2013/02/…Timer("SettingUp", false).schedule(500) doSomething()
它确实编译,如果你添加这两个导入:import java.util.Timer 和 import kotlin.concurrent.schedule
@Matias Elorriaga,对我来说,把它放在一个新的品牌文件上是不会编译的,甚至添加定制器说的导入
你不需要把它放在一个文件中,那个方法是stdlib的一部分,点击答案第一行的链接,
我原本以为即使在导入 kotlin.concurrent.schedule
之后也无法编译,因为 Kotlin 只是抱怨签名不匹配,但后来我意识到我试图传递一个 Int 而不是 Long。它在更正后编译。【参考方案2】:
还有一个选项可以使用Handler -> postDelayed
Handler().postDelayed(
//doSomethingHere()
, 1000)
【讨论】:
请补充一点,它仅在 android 上可用,因为问题要求使用一般的 kotlin 方法(尽管它确实有 Android 标签) 从您的角度来看,这不是建设性的。结果当用户搜索android标签时可能会认为这是错误的答案。 对于Android,最好使用Handler而不是Timer:***.com/questions/20330355/timertask-or-handler 我认为,您应该添加一个用于在活动/片段完成后删除处理程序的代码。 如果您打算这样做,它将不会在 UI 线程上运行。【参考方案3】:val timer = Timer()
timer.schedule(timerTask nextScreen() , 3000)
【讨论】:
你能解释一下为什么我需要写“timerTask”而不是大括号吗? 我想你会的。Timer.schedule()
期望 TimerTask
作为它的第一个参数。 kotlin.concurrent.timerTask()
将给定的 lambda 包装在 TimerTask
实例中。见这里:kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/…
此外,如果Timer
对象不会被多次使用,例如Timer().schedule(timerTask ... , 3000)
,则可以将给定示例压缩为一行。还有一个更适合 Kotlin 的选项;见 jonguer 的回答。【参考方案4】:
3 秒后显示敬酒的简单示例:
fun onBtnClick()
val handler = Handler()
handler.postDelayed( showToast() , 3000)
fun showToast()
Toast.makeText(context, "Its toast!", Toast.LENGTH_SHORT).show()
【讨论】:
我可以取消通话吗?【参考方案5】:你必须导入以下两个库:
import java.util.*
import kotlin.concurrent.schedule
然后以这种方式使用它:
Timer().schedule(10000)
//do something
【讨论】:
【参考方案6】:如果您正在寻找通用用法,这是我的建议:
创建一个名为Run
的类:
class Run
companion object
fun after(delay: Long, process: () -> Unit)
Handler().postDelayed(
process()
, delay)
并像这样使用:
Run.after(1000,
// print something useful etc.
)
【讨论】:
您可以将其简化为扩展功能 @Ogulcan,更多 kotlinic lamdaRun.after(1000) toRun()
。我说的对吗【参考方案7】:
你可以launch
一个协程,delay
它然后调用函数:
/*GlobalScope.*/launch
delay(1000)
yourFn()
如果您在一个类或对象之外,请在前面添加GlobalScope
让协程在那里运行,否则建议在周围的类中实现CoroutineScope
,这样可以在必要时取消与该范围关联的所有协程.
【讨论】:
谢谢!奇怪,协程是在 2018 年才被提及的。 @coolMind 它们已经稳定了几个月,所以它们很新...... 是的,从 10 月到 11 月,但之前存在。【参考方案8】:多种方式
1。使用Handler
类
Handler().postDelayed(
TODO("Do something")
, 2000)
2。使用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")
3。使用Executors
类
Executors.newSingleThreadScheduledExecutor().schedule(
TODO("Do something")
, 2, TimeUnit.SECONDS)
【讨论】:
您认为这里最好的解决方案是什么? 可能是第一个使用 Handler 的。见***.com/a/40339630/1159930【参考方案9】:我推荐使用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。
【讨论】:
【参考方案10】:如果您使用的是较新的 Android API,则不推荐使用 Handler 空构造函数,您应该包含 Looper。您可以通过Looper.getMainLooper()
轻松获得。
Handler(Looper.getMainLooper()).postDelayed(
//Your code
, 2000) //millis
【讨论】:
【参考方案11】:如果您在具有 viewModel 范围的片段中,则可以使用 Kotlin 协程:
myViewModel.viewModelScope.launch
delay(2000)
// DoSomething()
【讨论】:
【参考方案12】:我建议使用 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()
【讨论】:
以上是关于Kotlin延迟后如何调用函数?的主要内容,如果未能解决你的问题,请参考以下文章
函数返回后 Observable.forkJoin 调用延迟