Get in touch
or send us a question?
CONTACT

Android JetPack – WorkManager

WorkManager là gì?

WorkManager là một phần thư viện của Android Jetpack, giúp bạn dễ dàng lên lịch các tác vụ không đồng bộ, được dự kiến ​​sẽ chạy ngay cả khi ứng dụng thoát hoặc khởi động lại thiết bị, tức là ngay cả ứng dụng của bạn khởi động lại do bất kỳ vấn đề nào Trình quản lý công việc đảm bảo tác vụ theo lịch trình. WorkManager là sự thay thế phù hợp và được khuyến nghị cho tất cả các API lập lịch nền Android trước đây, và quan trọng là nó chạy trên API 14+ (vậy là đủ để chạy trên 99,99% thiết bị rồi 😀 )

If the device is running on API Level 23 or higher, JobScheduler is used. On
API Levels 14-22, GcmNetworkManager is chosen if it’s available, otherwise, a
custom AlarmManager and BroadcastReciever implementation is used as a
fallback.

Ngoài việc cung cấp một API đơn giản và nhất quán, WorkManager có một số lợi ích chính khác, bao gồm:

Work Constraints

Xác định rõ ràng các điều kiện tối ưu để công việc của bạn chạy bằng cách sử dụng các ràng buộc. (Ví dụ: chỉ chạy khi thiết bị đang bật Wi-Fi, khi thiết bị ở chế độ chờ hoặc khi có đủ dung lượng lưu trữ, v.v.)

Robust Scheduling

WorkManager cho phép bạn lên lịch công việc để chạy một lần hoặc nhiều lần bằng cách sử dụng các cửa sổ lập lịch linh hoạt

Flexible Retry Policy

Đôi khi công việc không thành công. WorkManager cung cấp các chính sách thử lại linh hoạt.

Work Chaining

Đối với công việc liên quan phức tạp, chúng có thể xâu chuỗi các nhiệm vụ công việc riêng lẻ lại với nhau cho phép bạn kiểm soát phần nào chạy tuần tự và phần nào chạy song song.

Built-In Threading Interoperability

WorkManager cung cấp khả năng linh hoạt để tương thích các API không đồng bộ của riêng bạn.

Tích hợp Work Manager

Thêm dependencies trong build.gradle file:

dependencies {
    val work_version = "2.7.0"

    // (Java only)
    implementation("androidx.work:work-runtime:$work_version")

    // Kotlin + coroutines
    implementation("androidx.work:work-runtime-ktx:$work_version")

    // optional - RxJava2 support
    implementation("androidx.work:work-rxjava2:$work_version")

    // optional - GCMNetworkManager support
    implementation("androidx.work:work-gcm:$work_version")

    // optional - Test helpers
    androidTestImplementation("androidx.work:work-testing:$work_version")

    // optional - Multiprocess support
    implementation "androidx.work:work-multiprocess:$work_version"
}

Define the work

Bây giờ, chúng ta sẽ tạo một class kế thừa class Worker. Class này chịu trách nhiệm thực hiện công việc đồng bộ trên một luồng nền do người quản lý công việc cung cấp trong hàm doWork(). Ví dụ 1 class Worker thực hiện nhiệm vụ upload ảnh.

class UploadWorker(appContext: Context, workerParams: WorkerParameters):
       Worker(appContext, workerParams) {
   override fun doWork(): Result {

       // Do the work here--in this case, upload the images.
       uploadImages()

       // Indicate whether the work finished successfully with the Result
       return Result.success()
   }
}

Kết quả trả về:

  • Result.success(): Thông báo công việc thực hiện thành công.
  • Result.failure(): Công việc thực hiện thất bại.
  • Result.retry(): Công việc thật bại và nên được thử lại vào thời điểm khác.

Tạo một WorkRequest

Sau khi tạo công việc; chúng ta sẽ lên lịch với dịch vụ WorkManager để chạy. Bạn có thể lập lịch để nó chạy định kỳ trong một khoảng thời gian hoặc bạn có thể lên lịch để nó chỉ chạy một lần.

Schedule one-time work

Tạo một work request chỉ chạy 1 lần:

val uploadWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       // Additional configuration
       .build()

Schedule periodic work

Lên lịch làm việc định kì (ví dụ: đồng bộ dữ liệu, backup data, download refresh, …)

val saveRequest =
       PeriodicWorkRequestBuilder<SaveImageToFileWorker>(1, TimeUnit.HOURS)
    // Additional configuration
           .build()

Trong ví dụ trên chúng ta đặt lịch cho công việc chạy sau 1h 1 lần. Tuy nhiên công việc sẽ chạy cách nhau tối thiểu 1h tuỳ thuộc vào sức khoẻ của thiết bị hoặc các điều kiện quy định (pin, internet …)

Chú ý: thời gian tối thiểu giữa 2 lần làm việc được đặt lịch nhỏ nhất là 15 phút.

val myUploadWork = PeriodicWorkRequestBuilder<SaveImageToFileWorker>(
       1, TimeUnit.HOURS, // repeatInterval (the period cycle)
       15, TimeUnit.MINUTES) // flexInterval
    .build()

Ngoài ra, chúng ta còn có thể đặt thời gian linh hoạt để công việc có thể hoạt động linh hoạt hơn như ví dụ trên.

You can set a flex interval for a periodic job. You define a repeat interval, and a flex interval that specifies a certain amount of time at the end of the repeat interval. WorkManager attempts to run your job at some point during the flex interval in each cycle.

Như vậy công việc có thể linh hoạt chạy trong thời gian định sẵn (flex period) cho đến khi một vòng lặp tiếp theo được chạy.

Tạo các ràng buộc điều kiện cho công việc.

Chúng ta có thể delay lại công việc theo khoảng thời gian được thiết lập hay tạo các điều kiện thích hợp để thực hiện tác vụ. Các điều kiện trong work manager gồm có:

  • NetworkType: Loại network: wifi/3g…
  • BatteryNotLow
  • RequiresCharging
  • DeviceIdle: Công việc chạy ngầm khi thiết bị ở chế độ nghỉ.
  • StorageNotLow: Công việc sẽ không chạy nếu bộ nhớ trống quá ít
val constraints = Constraints.Builder()
   .setRequiredNetworkType(NetworkType.UNMETERED)
   .setRequiresCharging(true)
   .build()

val myWorkRequest: WorkRequest =
   OneTimeWorkRequestBuilder<MyWork>()
       .setConstraints(constraints)
       .build()

Gửi WorkRequest tới hệ thống

Cuối cùng, chúng ta chỉ cần đưa workrequest tới workmanager sử dụng hàm enqueue():

WorkManager
    .getInstance(myContext)
    .enqueue(uploadWorkRequest)

Như vậy công việc của bạn sẽ được chạy theo thiết lập ngay cả khi ứng dụng tắt hoặc ở chế độ background.

Trên đây phần giới thiệu của mình về Work Manager. Ngoài ra các bạn có thể tìm hiểu thêm các tính năng khác chi tiết hơn theo nguồn dưới đây. Rất cảm ơn các bạn đã đón đọc.

https://developer.android.com/topic/libraries/architecture/workmanager/basics#kotlin