Bagaimana cara memanggil fungsi setelah penundaan di Kotlin?

154

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

Nguyen Minh Binh
sumber

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()
}
Matias Elorriaga
sumber
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)
Bogdan Ustyak
sumber
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)
Khemraj
sumber
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
}
jonguer
sumber
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.

Jonas Wilms
sumber
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)
varghesekutty
sumber
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()
}
Zeero0
sumber
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.
})
Ogulcan Orhan
sumber
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

canerkaseler
sumber