Kotlin延迟后如何调用函数?

Posted

技术标签:

【中文标题】Kotlin延迟后如何调用函数?【英文标题】:How to call a function after delay in Kotlin? 【发布时间】:2017-09-06 23:59:45 【问题描述】:

如题,KotlinKotlin中延迟(例如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 lamda Run.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延迟后如何调用函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在延迟的情况下调用 jquery 函数 onload?

如何在延迟的情况下调用 jquery 函数 onload?

如何在可组合函数回调中调用 Kotlin 协程?

函数返回后 Observable.forkJoin 调用延迟

如何从 Android 调用 Java/Kotlin GCP 云函数

如何延迟函数调用? [复制]