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.