Tạo luồng trong Worker

Stay organized with collections Save and categorize content based on your preferences.

Khi bạn sử dụng một Worker, WorkManager sẽ tự động gọi Worker.doWork() trên một luồng chạy nền (background thread). Luồng chạy nền do Executor thực thi được chỉ định trong Configuration của WorkManager. Theo mặc định, WorkManager sẽ thiết lập Executor cho bạn, nhưng bạn cũng có thể chỉnh theo ý mình. Ví dụ, bạn có thể chia sẻ một Trình thực thi hiện đang chạy nền trong ứng dụng của mình, tạo một Executor đơn luồng để đảm bảo thực thi tuần tự mọi công việc chạy nền của bạn hoặc thậm chí là chỉ định một Executor tuỳ chỉnh. Để tuỳ chỉnh Executor, cần đảm bảo rằng bạn khởi chạy WorkManager theo cách thủ công.

Khi định cấu hình WorkManager theo cách thủ công, bạn có thể chỉ định Executor như sau:

Kotlin

WorkManager.initialize(
    context,
    Configuration.Builder()
         // Uses a fixed thread pool of size 8 threads.
        .setExecutor(Executors.newFixedThreadPool(8))
        .build())

Java

WorkManager.initialize(
    context,
    new Configuration.Builder()
        .setExecutor(Executors.newFixedThreadPool(8))
        .build());

Dưới đây là ví dụ về một Worker đơn giản để tải nội dung của một trang web xuống 100 lần:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }
        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; i++) {
            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }

}

Lưu ý rằng Worker.doWork() là một lệnh gọi đồng bộ. Bạn cần thực hiện toàn bộ công việc chạy nền của mình theo kiểu chặn và hoàn tất chúng khi phương thức này thoát. Nếu bạn gọi một API không đồng bộ trong doWork() và được trả về một Result, thì lệnh gọi lại có thể đã không hoạt động đúng cách. Nếu gặp phải trường hợp này, bạn hãy sử dụng ListenableWorker (vui lòng xem phần Tạo luồng trong ListenableWorker).

Khi Worker đang chạy bị dừng vì bất kỳ lý do nào, lớp này sẽ nhận được lệnh gọi đếnWorker.onStopped() , Hãy ghi đè phương thức này hoặc gọi Worker.isStopped()để kiểm tra mã của bạn và giải phóng tài nguyên khi cần thiết. Khi Worker trong ví dụ trên bị dừng, lớp này có thể đang trong vòng lặp tải xuống các mục. Quá trình tải xuống sẽ vẫn tiếp tục mặc dù lớp này đã bị dừng. Để tối ưu hoá hành vi này, bạn có thể làm những việc như sau:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            if (isStopped) {
                break
            }

            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }

        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; ++i) {
            if (isStopped()) {
                break;
            }

            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }
}

Khi bạn đã dừng Worker, Result sẽ bị bỏ qua bất kể Worker.doWork() trả về kết quả gì.