Kotlin'de gecikmeden sonra bir işlevi nasıl arayabilirim?


154

Başlık olarak, gecikmeden sonra (örneğin 1 saniye) bir işlevi çağırmanın herhangi bir yolu var Kotlinmı?

Yanıtlar:


134

Zamanlamayı kullanabilirsiniz

inline fun Timer.schedule(
    delay: Long, 
    crossinline action: TimerTask.() -> Unit
): TimerTask (source)

örnek (teşekkürler @Nguyen Minh Binh - burada buldum: 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()
}

16
Teşekkürler! Süper kolay. Burada bir örnek bulundu jamie.mccrindle.org/2013/02/… Timer("SettingUp", false).schedule(500) { doSomething() }
Nguyen Minh Binh

9
Bu iki içe aktarmayı eklerseniz derleme yapar: import java.util.Timer ve import kotlin.concurrent.schedule
Customizer

3
@Matias Elorriaga, benim için bunu yeni bir marka dosyasına koymak derlenmiyor, hatta ithalatçı ekleyerek Customizer dedi
Sulfkain

3
bir dosyaya koymanıza gerek yoktur, bu yöntem stdlib'in bir parçasıdır, cevabın ilk satırındaki bağlantıyı takip edin,
Matias Elorriaga

3
Başlangıçta bunun içe kotlin.concurrent.scheduleaktarıldıktan sonra bile derlenmeyeceğini düşündüm , çünkü Kotlin sadece bir imza uyuşmazlığından şikayet etti, ancak sonra Long yerine bir Int'yi geçmeye çalıştığımı fark ettim. Bunu düzelttikten sonra derledi.
Joe Lapp

178

Kullanmak için bir seçenek de var Handler -> postDelayed

 Handler().postDelayed({
                    //doSomethingHere()
                }, 1000)

18
Soru sadece genel bir kotlin yöntemi istediğinden (Android etiketi olmasına rağmen) sadece android'de kullanılabilir olduğunu ekleyin
Yoav Sternberg

5
Sizin açınızdan yapıcı değil. Sonuç olarak kullanıcılar android etiketi arayacaklarında bunun yanlış cevap olduğunu düşünebilirler.
Bogdan Ustyak

9
Android için, Zamanlayıcıdan daha Handler kullanmak daha iyidir: stackoverflow.com/questions/20330355/timertask-or-handler
woprandi 20:18

Etkinlik / parça bittikten sonra işleyicileri kaldırmak için bir kod eklemeniz gerektiğini düşünüyorum.
CoolMind

Bunu yapmak istiyorsanız, UI iş parçacığında çalışmaz.
AndroidDev

93

Çok şekilde

1. HandlerSınıfı kullanma

Handler().postDelayed({
    TODO("Do something")
    }, 2000)

2. TimerSınıfı kullanma

Timer().schedule(object : TimerTask() {
    override fun run() {
        TODO("Do something")
    }
}, 2000)

Daha kısa

Timer().schedule(timerTask {
    TODO("Do something")
}, 2000)

En kısa

Timer().schedule(2000) {
    TODO("Do something")
}

3. ExecutorsSınıfı kullanma

Executors.newSingleThreadScheduledExecutor().schedule({
    TODO("Do something")
}, 2, TimeUnit.SECONDS)

1
ve sizce buradaki en iyi çözüm nedir?
Tamim Attafi

1
Muhtemelen ilk işleyici kullanan. Bkz. Stackoverflow.com/a/40339630/1159930
Markymark

36

Aşağıdaki iki kütüphaneyi içe aktarmanız gerekir:

import java.util.*
import kotlin.concurrent.schedule

ve bundan sonra bu şekilde kullanın:

Timer().schedule(10000){
    //do something
}

27

launchBir koroutin olabilir , delayve sonra işlevi çağırabilirsiniz:

 /*GlobalScope.*/launch {
   delay(1000)
   yourFn()
 }

GlobalScopeKoroutinin orada çalışmasına izin vermek için bir sınıfın veya nesnenin dışındaysanız, aksi takdirde CoroutineScopeçevredeki sınıfta uygulanması önerilir; bu, gerekirse o kapsamla ilişkili tüm koroutinlerin iptal edilmesine izin verir.


Teşekkürler! Tuhaf, bu coroutines sadece 2018'de bahsedildi.
CoolMind

@coolMind birkaç aydan beri stabiller, bu yüzden oldukça yeniler ...
Jonas Wilms

Evet, ekim-kasım ayları arasında, ancak daha önce vardı.
CoolMind

23
val timer = Timer()
timer.schedule(timerTask { nextScreen() }, 3000)

1
Lütfen neden sadece parantez yerine "timerTask" yazmam gerektiğini açıklayabilir misiniz?
Hugo Passos

2
Bence yaparsın. Timer.schedule()a TimerTaskilk argüman olarak bekler . kotlin.concurrent.timerTask()verilen lambda'yı bir TimerTaskörnekte sarar . Buraya bakın: kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/…
Blieque

Ayrıca, Timernesne bir kereden fazla kullanılmayacaksa , verilen örnek bir satıra yoğunlaştırılabilir , örn Timer().schedule(timerTask { ... }, 3000). Daha Kotlin dostu bir seçenek de mevcuttur; jonguer'in cevabına bakınız.
Blieque

10

3 saniye sonra bir tost göstermek için basit bir örnek :

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

fun showToast(){
    Toast.makeText(context, "Its toast!", Toast.LENGTH_SHORT).show()
}

1
aramayı iptal edebilir miyim?
Eduardo Oliveros

6

Genel kullanım arıyorsanız, işte önerim:

Şu şekilde adlandırılan bir sınıf oluşturun Run:

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

Ve şöyle kullanın:

Run.after(1000, {
    // print something useful etc.
})

Bunu uzatma işlevi olarak basitleştirebilirsiniz
Vlad

@Ogulcan, daha kotlinic lamda Run.after(1000) { toRun() }. Am I correct
binrebin

0

SingleThread'i kullanmanızı öneriyorum çünkü kullandıktan sonra onu öldürmek zorunda değilsiniz. Ayrıca Kotlin dilinde " stop ()" yöntemi kullanımdan kaldırılmıştır.

private fun mDoThisJob(){

    Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate({
        //TODO: You can write your periodical job here..!

    }, 1, 1, TimeUnit.SECONDS)
}

Ayrıca, periyodik iş için kullanabilirsiniz. Bu çok kullanışlı. Her saniye için iş yapmak istiyorsanız, bunun parametrelerini ayarlayabilirsiniz:

Executors.newSingleThreadScheduledExecutor (). ScheduleAtFixedRate (Çalıştırılabilir komut, uzun initialDelay, uzun dönem, TimeUnit birimi);

TimeUnit değerleri: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS.

@canerkaseler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.