Skip to Content
Kotlin⚡ Kotlin CoroutinesGiới thiệu Coroutines

Giới thiệu Kotlin Coroutines

Coroutines là gì?

Coroutines là cách Kotlin xử lý lập trình bất đồng bộ (asynchronous programming). Chúng cho phép bạn viết code “trông như” đồng bộ nhưng thực sự chạy bất đồng bộ mà không block thread.

Vấn đề: Tại sao cần bất đồng bộ?

Khi app Android gọi API hoặc đọc file:

// ❌ SAI: Block UI thread -> App bị đơ (ANR) fun loadData() { val data = networkCall() // Mất 3 giây updateUI(data) // User không thể tương tác trong 3 giây! }

Android có quy tắc: UI thread (Main thread) không được làm việc nặng (network, database, file I/O).

Giải pháp cũ: Callbacks

// Callback hell - Code khó đọc, khó maintain api.getUser(userId) { user -> api.getPosts(user.id) { posts -> api.getComments(posts[0].id) { comments -> // Nested callbacks... updateUI(user, posts, comments) } } }

Giải pháp tốt hơn: Coroutines

// ✅ Clean và dễ đọc như code đồng bộ suspend fun loadData() { val user = api.getUser(userId) // Đợi, nhưng không block! val posts = api.getPosts(user.id) // Tiếp tục sau khi user có val comments = api.getComments(posts[0].id) updateUI(user, posts, comments) }

Magic: Code trông như chạy lần lượt, nhưng thực ra:

  • Khi gọi getUser(), coroutine suspend (tạm dừng) và giải phóng thread
  • Thread có thể làm việc khác
  • Khi data về, coroutine resume (tiếp tục) từ đúng chỗ dừng

Coroutines vs Threads

CoroutinesThreads
Tạo mớiRất nhẹ (vài KB)Nặng (~1-2 MB)
Số lượngHàng triệuVài nghìn
Quản lýTự động (structured concurrency)Manual
CancelDễ dàngPhức tạp
ExceptionPropagate tự độngDễ bị nuốt

Demo: 100,000 coroutines vs threads

// Coroutines: Hoạt động bình thường (~300ms) fun main() = runBlocking { repeat(100_000) { launch { delay(1000) print(".") } } } // Threads: OutOfMemoryError! fun main() { repeat(100_000) { Thread { Thread.sleep(1000) print(".") }.start() } }

Các khái niệm cốt lõi

1. Suspend Function

Hàm có thể tạm dừng mà không block thread:

suspend fun fetchData(): Data { delay(1000) // Tạm dừng 1 giây (không block!) return Data() }

2. Coroutine Builder

Cách khởi chạy coroutine:

// launch - Fire and forget launch { fetchData() } // async - Trả về kết quả val deferred = async { fetchData() } val result = deferred.await()

3. Coroutine Scope

Phạm vi quản lý lifecycle của coroutines:

// ViewModel scope - tự cancel khi ViewModel bị clear viewModelScope.launch { // ... } // Lifecycle scope - tự cancel khi lifecycle destroyed lifecycleScope.launch { // ... }

4. Dispatcher

Thread pool nơi coroutine chạy:

// Main thread (UI) Dispatchers.Main // Background thread (I/O operations) Dispatchers.IO // CPU-intensive work Dispatchers.Default

Ví dụ thực tế: Gọi API

class UserViewModel : ViewModel() { private val _user = MutableStateFlow<User?>(null) val user: StateFlow<User?> = _user.asStateFlow() fun loadUser(userId: Int) { // Chạy trong ViewModel scope viewModelScope.launch { try { // Chuyển sang IO thread để gọi network val result = withContext(Dispatchers.IO) { api.getUser(userId) } // Quay về Main thread để update UI _user.value = result } catch (e: Exception) { // Xử lý lỗi } } } }

So sánh với các giải pháp khác

RxJava

// RxJava - Học curve cao, boilerplate nhiều api.getUser(userId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ user -> updateUI(user) }, { error -> handleError(error) })

Coroutines

// Coroutines - Đơn giản hơn nhiều viewModelScope.launch { try { val user = withContext(Dispatchers.IO) { api.getUser(userId) } updateUI(user) } catch (e: Exception) { handleError(e) } }

Setup Coroutines

Thêm dependencies

// build.gradle.kts dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // Cho Android }

📝 Tóm tắt

Khái niệmMô tả
CoroutineUnit of async work, nhẹ hơn thread
suspendTạm dừng mà không block
launchKhởi chạy coroutine (fire-and-forget)
async/awaitKhởi chạy và lấy kết quả
ScopeQuản lý lifecycle
DispatcherThread pool

Lý do học Coroutines

  1. Official - Được Kotlin và Google khuyến nghị
  2. Simple - Code dễ đọc như synchronous
  3. Efficient - Nhẹ, có thể chạy hàng triệu
  4. Structured - Tự động cancel, exception handling tốt
  5. Integrate - Tích hợp tốt với Android Jetpack

Tiếp theo

Học về Suspend Functions - nền tảng của coroutines.

Last updated on