ภาพรวม
Kotlin รองรับการเรียกฟังก์ชันแบบ Asynchronous หลังหน่วงเวลา (Delay) หลายวิธี ตั้งแต่ Java Timer ไปจนถึง Coroutines ที่ทันสมัย
วิธีที่ 1: Java Timer & TimerTask (Legacy)
import java.util.Timer
import java.util.TimerTask
fun main() {
println("Start")
Timer().schedule(5000) { // 5000 ms = 5 วินาที
delayedFunction()
}
println("End (non-blocking)")
Thread.sleep(6000) // รอให้โปรแกรมไม่จบก่อน
}
fun delayedFunction() {
println("Delayed method call!")
}
วิธีที่ 2: Handler (Android Only)
// ใน Android Activity/Fragment
import android.os.Handler
import android.os.Looper
fun delayOnMainThread(delayMs: Long, action: () -> Unit) {
Handler(Looper.getMainLooper()).postDelayed(action, delayMs)
}
// ใช้งาน
delayOnMainThread(3000) {
println("Run on Main Thread after 3s")
}
วิธีที่ 3: Kotlin Coroutines (แนะนำ - Modern)
import kotlinx.coroutines.*
fun main() = runBlocking {
println("Start")
// Launch coroutine ที่ delay แล้วรัน
launch {
delay(2000) // Non-blocking delay
delayedFunction()
}
println("End (non-blocking)")
// runBlocking รอ coroutine ทั้งหมดจบ
}
fun delayedFunction() {
println("Delayed with Coroutine!")
}
Coroutine Scope ใน Android (lifecycle-aware)
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
// ใน Activity/Fragment
lifecycleScope.launch {
delay(5000)
// Auto-cancel เมื่อ Lifecycle ถูก Destroy
updateUI()
}
วิธีที่ 4: Thread.sleep (Blocking - ไม่แนะนำสำหรับ Main Thread)
fun main() {
println("Before")
Thread.sleep(2000) // Block thread 2 วินาที
println("After 2 seconds")
}
⚠️ ห้ามใช้ใน Main Thread (UI Thread) จะทำให้แอปค้าง (ANR)
ตารางเปรียบเทียบ
| วิธี | Platform | Blocking? | Lifecycle Aware? | แนะนำ? |
|---|---|---|---|---|
| Timer/TimerTask | JVM/All | No | No | Legacy only |
| Handler | Android | No | Manual | Simple UI Delay |
| Coroutines | Multiplatform | No (suspend) | Yes (lifecycleScope) | ✅ Best Practice |
| Thread.sleep | JVM | Yes | No | ❌ ไม่ใช้ Main Thread |
สรุป
- Kotlin/JVM ทั่วไป: ใช้
kotlinx.coroutines(delay + launch) - Android UI: ใช้
lifecycleScope.launch { delay() }หรือHandler(Looper.getMainLooper()).postDelayed - หลีกเลี่ยง:
Thread.sleep()บน Main Thread,Timerสำหรับโค้ดใหม่