0Pricing
Android Academy · บทเรียน

โครูทีนและฟังก์ชัน Suspend

เขียนโค้ดแบบอะซิงโครนัสที่อ่านได้เหมือนโค้ดแบบซิงโครนัส ใช้ฟังก์ชัน suspend ขอบเขตโครูทีน และตัวจัดส่ง (IO, Main, Default)

โครูทีนและฟังก์ชัน Suspend เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 6 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 6 บทเรียน

ปัญหา: การบล็อกเธรด UI

Android เรียกใช้งานทั้งหมดของ UI บน เธรดหลัก หากคุณส่งคำขอเครือข่ายหรืออ่านฐานข้อมูลบนเธรดหลัก UI จะ ค้าง จนกว่าการทำงานนั้นจะเสร็จสิ้น

หาก UI ค้างนานกว่า 5 วินาที Android จะแสดงกล่องโต้ตอบ ANR (แอปไม่ตอบสนอง) และผู้ใช้สามารถบังคับปิดแอปของคุณได้

Coroutines คืออะไร

Kotlin Coroutines เป็นวิธีเขียนโค้ดแบบไม่พร้อมกันให้มีลักษณะ เหมือนทำงานตามลำดับ โดยไม่ต้องใช้ Callback หรือสายการทำงานของ RxJava

  • น้ำหนักเบา — โครูทีนนับพันสามารถทำงานพร้อมกันได้
  • หยุดพักได้ — โครูทีนสามารถหยุดชั่วคราวและทำงานต่อได้โดยไม่บล็อกเธรด
  • มีโครงสร้าง — เคารพวงจรชีวิตผ่านขอบเขตการทำงาน

ฟังก์ชัน suspend

ฟังก์ชันที่ระบุด้วย suspend สามารถหยุดการทำงานชั่วคราวโดยไม่บล็อกเธรด และสามารถถูกเรียกได้จากฟังก์ชัน suspend อื่นหรือขอบเขตของโครูทีนเท่านั้น

import kotlinx.coroutines.*

suspend fun fetchData(): String {
    delay(1000)  // simulates 1 second network call
    return "Data loaded!"
}

fun main() = runBlocking {
    println("Fetching...")
    val result = fetchData()  // suspends here, doesn't block
    println(result)           // Data loaded!
    println("Done")
}

ขอบเขตของโครูทีน

โครูทีนทุกตัวทำงานอยู่ภายในขอบเขตที่กำหนดวงจรชีวิตของมัน:

  • viewModelScope — ถูกยกเลิกเมื่อ ViewModel ถูกล้าง
  • lifecycleScope — ถูกยกเลิกเมื่อ Activity/Fragment ถูกทำลาย
  • GlobalScope — คงอยู่ตลอดไป (ควรหลีกเลี่ยง)
  • runBlocking — ใช้สำหรับการทดสอบเท่านั้น

launch เทียบกับ async

มีสองวิธีในการเริ่มโครูทีน:

  • launch { } — เริ่มทำงานแล้วไม่รอผลลัพธ์ ไม่มีค่าที่ส่งคืน
  • async { }.await() — ส่งคืนผลลัพธ์ที่คุณสามารถรอรับได้
import kotlinx.coroutines.*

fun main() = runBlocking {
    // launch: no return value
    launch {
        delay(500)
        println("launch done")
    }

    // async: returns a Deferred<T>
    val deferred = async {
        delay(300)
        42
    }
    val result = deferred.await()
    println("async result: $result")
}

Dispatchers: เธรดใด

Dispatchers ควบคุมว่าโคโรทีนจะทำงานบนเธรดใด:

  • Dispatchers.Main — เธรด UI (สำหรับอัปเดตมุมมอง)
  • Dispatchers.IO — สำหรับการทำงานกับเครือข่ายและดิสก์
  • Dispatchers.Default — สำหรับงานที่ใช้ CPU มาก

ใช้ withContext(Dispatchers.IO) { } เพื่อสลับตัวจัดส่งภายในโคโรทีน

ตัวอย่าง viewModelScope

ดึงข้อมูลใน ViewModel โดยไม่บล็อก UI:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*

class DataViewModel : ViewModel() {

    fun loadData() {
        viewModelScope.launch {
            // Switch to IO thread for network
            val data = withContext(Dispatchers.IO) {
                // simulate network request
                delay(1000)
                "Result from server"
            }
            // Back on Main thread — safe to update UI
            _uiState.value = data
        }
    }
}

การจัดการข้อผิดพลาดในโคโรทีน

จัดการข้อยกเว้นภายในโคโรทีนด้วย try/catch เช่นเดียวกับโค้ดทั่วไป:

viewModelScope.launch {
    try {
        val result = withContext(Dispatchers.IO) {
            api.fetchUser()  // may throw IOException
        }
        _user.value = result
    } catch (e: Exception) {
        _error.value = "Failed: ${e.message}"
    }
}

โคโรทีนแบบขนาน

เรียกใช้งานสองงานแบบขนานและรอให้ทั้งคู่เสร็จสิ้นด้วย async/await:

viewModelScope.launch {
    // Both run at the same time!
    val userDeferred = async(Dispatchers.IO) { api.getUser() }
    val postsDeferred = async(Dispatchers.IO) { api.getPosts() }

    val user = userDeferred.await()
    val posts = postsDeferred.await()

    _state.value = UiState(user, posts)
}

ตรวจสอบอย่างรวดเร็ว

ควรใช้ตัวจัดส่งโคโรทีนใดสำหรับการทำงานกับเครือข่ายและฐานข้อมูล

ทบทวน: โคโรทีน

ตอนนี้คุณสามารถเขียนโค้ดแบบอะซิงโครนัสได้โดยไม่ต้องใช้ callback:

  • suspend fun — หยุดชั่วคราวได้โดยไม่บล็อกเธรด
  • viewModelScope.launch { } — เริ่มโคโรทีนใน ViewModel
  • withContext(Dispatchers.IO) — สลับไปใช้เธรดเบื้องหลัง
  • async { }.await() — ทำงานแบบขนานพร้อมรับผลลัพธ์
  • try/catch ทำงานตามปกติภายในโคโรทีน

ถัดไป: รูปแบบ Repository — การแยกแหล่งข้อมูลออกจากกันอย่างชัดเจน

คำถามที่พบบ่อย

บทเรียน “โครูทีนและฟังก์ชัน Suspend” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “โครูทีนและฟังก์ชัน Suspend” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 6 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “โครูทีนและฟังก์ชัน Suspend”

เขียนโค้ดแบบอะซิงโครนัสที่อ่านได้เหมือนโค้ดแบบซิงโครนัส ใช้ฟังก์ชัน suspend ขอบเขตโครูทีน และตัวจัดส่ง (IO, Main, Default) คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 6 บทเรียน

บทเรียน “โครูทีนและฟังก์ชัน Suspend” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม

ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ViewModel และ LiveData
  2. ฐานข้อมูล Room
  3. โครูทีนและฟังก์ชัน Suspend
  4. รูปแบบ Repository
  5. คอมโพเนนต์ Navigation
  6. การฉีด Dependency ด้วย Hilt
← กลับไปที่ Android Academy