Hướng dẫn chi tiết về Kotlin Coroutines cho Android Engineer
Chắc chắn rằng sau một thời gian làm việc với Kotlin Coroutines, nhiều bạn đã cảm thấy quen thuộc với các khái niệm cơ bản như các hàm suspend
, launch
, async
... và có thể giải quyết nhiều use case đơn giản một cách dễ dàng. Tuy nhiên, khi dự án của bạn trở nên phức tạp hơn, bạn sẽ cần phải tìm hiểu và áp dụng các giải pháp nâng cao hơn để đáp ứng nhu cầu phát triển.
Bài viết này sẽ tổng hợp những kiến thức quan trọng về Kotlin Coroutines mà mình đã tích lũy được trong quá trình làm việc, nhằm giúp bạn trở thành một Android Engineer thành thạo hơn trong việc sử dụng coroutines. Đây cũng sẽ là tài liệu tham khảo hữu ích cho bạn trong quá trình phát triển ứng dụng.
Tham khảo thêm
Bạn có thể tham khảo các phần khác trong chuỗi bài viết này:
- Kotlin Flow cheat sheet phần 1: Channel
- Kotlin Flow cheat sheet phần 2: Flow
- Kotlin Flow cheat sheet phần 3: SharedFlow và StateFlow
Các khái niệm cơ bản về Coroutines
Coroutine Context
CoroutineContext
là một tập hợp các thành phần khác nhau, trong đó có hai thành phần chính là Job và Dispatcher.
Job
Job là một đối tượng có thể hủy, và vòng đời của nó đạt đỉnh khi nó hoàn thành. Mỗi coroutine đều có một Job riêng, không kế thừa từ coroutine cha.
Dispatcher
Dispatcher giúp chúng ta quyết định thread nào mà coroutine sẽ chạy trên đó. Đọc thêm trong bài viết của mình về Dispatchers trong Kotlin Coroutines.
Coroutine Scope
Coroutine Scope xác định thời gian tồn tại và context của coroutine, quản lý vòng đời của coroutine cùng việc xử lý lỗi.
Coroutine Builder
Các extension function của CoroutineScope
, cho phép khởi động một coroutine bất đồng bộ, như launch
, async
,…
Quy tắc quan trọng khi sử dụng Coroutines
- Cần có một
CoroutineScope
để bắt đầu một coroutine. - Coroutine con kế thừa
coroutine context
từ coroutine cha (trừ Job). Job
của coroutine cha là cha của Job của coroutine con.- Coroutine cha suspend cho đến khi tất cả các coroutine con kết thúc.
- Hủy coroutine cha sẽ dẫn đến hủy tất cả các coroutine con.
- Một coroutine con gặp phải lỗi do một exception không được xử lý sẽ hủy coroutine cha của nó.
- Tránh sử dụng
GlobalScope
để ngăn ngừa memory leak. - Không nên truyền coroutine scope như một tham số, sử dụng
coroutineScope
thay vào đó.
Các hàm trong Coroutine Scope
coroutineScope
: Khởi động một scope và trả về giá trị từ tham số của hàm.supervisorScope
: Tương tự nhưcoroutineScope
, nhưng không hủy các coroutine con khi có ngoại lệ.withContext
: Thay đổi scope (thường để thay đổi Dispatcher).withTimeout
: Đặt giới hạn thời gian cho body và hủy nếu quá thời gian cho phép.withTimeoutOrNull
: Tương tựwithTimeout
, nhưng trả vềnull
khi vượt quá thời gian.
Chạy song song với Coroutines
Khi bạn muốn thực hiện hai tác vụ đồng thời và chờ kết quả, bạn có thể làm như sau:
kotlin
suspend fun getConfigFromAPI(): UserConfig { /* Thực hiện lệnh gọi API */ }
suspend fun getSongsFromAPI(): List<Song> { /* Thực hiện lệnh gọi API */ }
fun getConfigAndSongs() {
vviewModelScope.launch { /* Code chạy song song */ }
}
Nếu bạn muốn tải xuống tất cả các trang, làm như sau:
kotlin
fun getAllSongs() {
scope.launch {
val allNews = (0 until totalNumberOfPages).map { page -> async { getSongsFromAPI(page) } }.flatMap { it.await() }
}
}
Lưu ý rằng async
sẽ khởi động coroutine ngay lập tức và trả về một đối tượng thuộc loại Deferred<T>
.
Dọn dẹp khi Coroutine bị hủy
Khi một coroutine bị hủy, hoàn toàn có thể thực hiện một số tác vụ dọn dẹp:
kotlin
viewModelScope.launch {
try { /* Gọi suspend function */ }
finally { /* Dọn dẹp */ }
}
Nếu cần gọi suspend function trong dọn dẹp, hãy sử dụng withContext(NonCancellable) {}
.
Các cách xử lý exception
Dùng SupervisorJob
để tránh hủy các coroutine khác khi có lỗi:
kotlin
val scope = CoroutineScope(SupervisorJob())
// Thực hiện các coroutine mà không ảnh hưởng lẫn nhau
Xử lý tác vụ không cần thiết
Để chạy các tác vụ không cần thiết mà không ảnh hưởng đến các tác vụ khác:
kotlin
nonEssentialOperationScope.launch { /* Tác vụ không cần thiết */ }
Kết luận
Hy vọng những kiến thức trong bài viết sẽ giúp bạn tận dụng hiệu quả Kotlin Coroutines trong dự án của mình. Nếu bạn có thêm mẹo hay hay chia sẻ, đừng ngần ngại comment dưới bài viết này nhé!
Các tài liệu tham khảo
🔔 Blog: henrytechie.com
☕️ Facebook: Henry Techie
☁️ TikTok: @henrytechie
source: viblo