Quan sát tiến trình trung gian của Worker

WorkManager bổ sung sự hỗ trợ hạng nhất cho việc cài đặt và quan sát tiến trình trung gian dành cho các trình thực thi (worker). Nếu trình thực thi này đang hoạt động trong khi ứng dụng ở nền trước, thì thông tin này cũng có thể hiển thị với người dùng sử dụng những API trả về LiveData của WorkInfo.

ListenableWorker hiện đã hỗ trợ API setProgressAsync(), cho phép API này duy trì tiến trình trung gian. Các API này giúp nhà phát triển thiết lập tiến trình trung gian mà giao diện người dùng có thể quan sát được. Tiến trình được biểu thị bằng loại Data, đây là một vùng chứa thuộc tính theo tuần tự (tương tự như inputoutput, cũng như phải tuân theo các quy định hạn chế giống nhau).

Bạn chỉ có thể quan sát và cập nhật thông tin của tiến trình khi ListenableWorker đang chạy. Hệ thống sẽ bỏ qua các nỗ lực thiết lập tiến trình trên ListenableWorker sau khi thực thi xong lớp này . Ngoài ra, bạn có thể quan sát thông tin tiến trình bằng cách sử dụng một trong các phương thức getWorkInfoBy…() hoặc getWorkInfoBy…LiveData(). Các phương thức này trả về những thực thể của WorkInfo, trong đó có một phương thức getProgress() mới trả về Data.

Đang cập nhật tiến trình

Đối với các nhà phát triển Java bằngListenableWorker hoặc Worker, API setProgressAsync() trả về một ListenableFuture<Void>; tiến trình cập nhật không đồng bộ vì quá trình cập nhật liên quan đến việc lưu trữ thông tin tiến trình trong cơ sở dữ liệu. Trong Kotlin, bạn có thể sử dụng hàm mở rộng setProgress() của đối tượng CoroutineWorker để cập nhật thông tin về tiến trình.

Ví dụ này cho thấy một ProgressWorker đơn giản. Worker thiết lập tiến trình là 0 khi bắt đầu và cập nhật tiến trình thành 100 sau khi hoàn thành.

Kotlin

import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.WorkerParameters
import kotlinx.coroutines.delay

class ProgressWorker(context: Context, parameters: WorkerParameters) :
    CoroutineWorker(context, parameters) {

    companion object {
        const val Progress = "Progress"
        private const val delayDuration = 1L
    }

    override suspend fun doWork(): Result {
        val firstUpdate = workDataOf(Progress to 0)
        val lastUpdate = workDataOf(Progress to 100)
        setProgress(firstUpdate)
        delay(delayDuration)
        setProgress(lastUpdate)
        return Result.success()
    }
}

Java

import android.content.Context;
import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

public class ProgressWorker extends Worker {

    private static final String PROGRESS = "PROGRESS";
    private static final long DELAY = 1000L;

    public ProgressWorker(
        @NonNull Context context,
        @NonNull WorkerParameters parameters) {
        super(context, parameters);
        // Set initial progress to 0
        setProgressAsync(new Data.Builder().putInt(PROGRESS, 0).build());
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            // Doing work.
            Thread.sleep(DELAY);
        } catch (InterruptedException exception) {
            // ... handle exception
        }
        // Set progress to 100 after you are done doing your work.
        setProgressAsync(new Data.Builder().putInt(PROGRESS, 100).build());
        return Result.success();
    }
}

Đang quan sát tiến trình

Việc quan sát thông tin tiến trình cũng khá đơn giản. Bạn có thể sử dụng các phương thứ getWorkInfoBy…() hoặc getWorkInfoBy…LiveData() và tham chiếu đến WorkInfo.

Dưới đây là ví dụ sử dụng API getWorkInfoByIdLiveData.

Kotlin

WorkManager.getInstance(applicationContext)
    // requestId is the WorkRequest id
    .getWorkInfoByIdLiveData(requestId)
    .observe(observer, Observer { workInfo: WorkInfo? ->
            if (workInfo != null) {
                val progress = workInfo.progress
                val value = progress.getInt(Progress, 0)
                // Do something with progress information
            }
    })

Java

WorkManager.getInstance(getApplicationContext())
     // requestId is the WorkRequest id
     .getWorkInfoByIdLiveData(requestId)
     .observe(lifecycleOwner, new Observer<WorkInfo>() {
             @Override
             public void onChanged(@Nullable WorkInfo workInfo) {
                 if (workInfo != null) {
                     Data progress = workInfo.getProgress();
                     int value = progress.getInt(PROGRESS, 0)
                     // Do something with progress
             }
      }
});

Để xem thêm tài liệu về quá trình quan sát các đối tượng Worker, hãy đọc Trạng thái công việc và công việc quan sát.