Bagaimana cara memanggil fungsi setelah penundaan di Kotlin?


154

Sebagai judul, apakah ada cara untuk memanggil fungsi setelah penundaan (misalnya 1 detik) Kotlin?

Jawaban:


134

Anda dapat menggunakan Jadwal

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

contoh (terima kasih @Nguyen Minh Binh - temukan di sini: 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
Terima kasih! Sangat mudah. Temukan contoh di sini jamie.mccrindle.org/2013/02/...Timer("SettingUp", false).schedule(500) { doSomething() }
Nguyen Minh Binh

9
Itu mengkompilasi, jika Anda menambahkan dua impor ini: impor java.util.Timer dan impor kotlin.concurrent.schedule
Penyesuai

3
@Matias Elorriaga, bagi saya, meletakkan ini pada file merek baru tidak dapat dikompilasi, bahkan menambahkan kata impor yang Customizer
Sulphkain

3
Anda tidak perlu meletakkannya di file, metode itu adalah bagian dari stdlib, ikuti tautan di baris pertama jawabannya,
Matias Elorriaga

3
Saya awalnya berpikir ini tidak akan dikompilasi bahkan setelah mengimpor kotlin.concurrent.schedule, karena Kotlin hanya mengeluhkan ketidakcocokan tanda tangan, tetapi kemudian saya menyadari bahwa saya mencoba untuk lulus Int bukan panjang. Itu dikompilasi setelah mengoreksi itu.
Joe Lapp

178

Ada juga opsi untuk digunakan Handler -> postDelayed

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

18
Harap tambahkan bahwa ini hanya tersedia di android, karena pertanyaannya meminta metode kotlin umum (walaupun ia memiliki tag Android)
Yoav Sternberg

5
Itu tidak konstruktif dari sisi Anda. Akibatnya ketika pengguna akan mencari tag Android mungkin berpikir ini adalah jawaban yang salah.
Bogdan Ustyak

9
Untuk Android, lebih baik menggunakan Handler daripada Timer: stackoverflow.com/questions/20330355/timertask-or-handler
woprandi

Saya pikir, Anda harus menambahkan kode untuk menghapus penangan setelah aktivitas / fragmen selesai.
CoolMind

Ini tidak akan berjalan pada utas UI jika Anda bermaksud melakukan itu.
AndroidDev

93

Banyak jalan

1. Menggunakan Handlerkelas

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

2. Menggunakan Timerkelas

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

Singkat

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

Terpendek

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

3. Menggunakan Executorskelas

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

1
dan menurut Anda apa solusi terbaik di sini?
Tamim Attafi

1
Mungkin yang pertama menggunakan Handler. Lihat stackoverflow.com/a/40339630/1159930
Markymark

36

Anda harus mengimpor dua perpustakaan berikut:

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

dan setelah itu gunakan cara ini:

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

27

Anda bisa launchmenggunakan coroutine, delaylalu memanggil fungsinya:

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

Jika Anda berada di luar kelas atau objek yang bergantung GlobalScopeuntuk membiarkan coroutine berjalan di sana, jika tidak disarankan untuk mengimplementasikannya CoroutineScopedi kelas sekitarnya, yang memungkinkan untuk membatalkan semua coroutine yang terkait dengan cakupan itu jika perlu.


Terima kasih! Aneh, coroutine itu hanya disebutkan pada tahun 2018.
CoolMind

@coolMind mereka stabil sejak beberapa bulan, jadi mereka cukup baru ...
Jonas Wilms

Ya, dari Oktober-November, tetapi sudah ada sebelumnya.
CoolMind

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

1
Bisakah Anda jelaskan mengapa saya perlu menulis "timerTask" bukan hanya kawat gigi?
Hugo Passos

2
Saya pikir Anda tahu. Timer.schedule()mengharapkan TimerTaskargumen pertama. kotlin.concurrent.timerTask()membungkus lambda yang diberikan dalam TimerTaskcontoh. Lihat di sini: kotlinlang.org/api/latest/jvm/stdlib/kotlin.concurrent/…
Blieque

Juga, contoh yang diberikan dapat diringkas menjadi satu baris jika Timerobjek tidak akan digunakan lebih dari sekali, misalnya Timer().schedule(timerTask { ... }, 3000),. Pilihan yang lebih ramah untuk Kotlin juga tersedia; lihat jawaban jonguer.
Blieque

10

Contoh sederhana untuk bersulang setelah 3 detik :

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

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

1
bisakah saya membatalkan panggilan?
Eduardo Oliveros

6

Jika Anda mencari penggunaan umum, berikut adalah saran saya:

Buat kelas dengan nama Run:

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

Dan gunakan seperti ini:

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

Anda dapat menyederhanakan ini sebagai ekstensi fucntion
Vlad

@ Ogulcan, lamda lebih kotlinik Run.after(1000) { toRun() }. Apakah saya benar
binrebin

0

Saya merekomendasikan menggunakan SingleThread karena Anda tidak perlu membunuhnya setelah menggunakan. Juga, metode " stop ()" tidak digunakan lagi dalam bahasa Kotlin.

private fun mDoThisJob(){

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

    }, 1, 1, TimeUnit.SECONDS)
}

Selain itu, Anda dapat menggunakannya untuk pekerjaan berkala. Itu sangat berguna. Jika Anda ingin melakukan pekerjaan untuk setiap detik, Anda dapat mengatur karena parameternya:

Executors.newSingleThreadScheduledExecutor (). ScheduleAtFixedRate (perintah Runnable, long initialDelay, periode lama, unit TimeUnit);

Nilai TimeUnit adalah: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS.

@canerkaseler

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.