0
0
Lập trình
Admin Team
Admin Teamtechmely

Hướng dẫn chi tiết về Kotlin Coroutines cho Android Engineer

Đăng vào 3 tuần trước

• 4 phút đọc

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à JobDispatcher.

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

  1. Cần có một CoroutineScope để bắt đầu một coroutine.
  2. Coroutine con kế thừa coroutine context từ coroutine cha (trừ Job).
  3. Job của coroutine cha là cha của Job của coroutine con.
  4. Coroutine cha suspend cho đến khi tất cả các coroutine con kết thúc.
  5. Hủy coroutine cha sẽ dẫn đến hủy tất cả các coroutine con.
  6. 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ó.
  7. Tránh sử dụng GlobalScope để ngăn ngừa memory leak.
  8. 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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
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

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào