Threading di Worker

Saat Anda menggunakan Worker, WorkManager otomatis memanggil Worker.doWork() pada thread latar belakang. Thread latar belakang berasal dari Executor yang ditentukan dalam Configuration WorkManager. Secara default, WorkManager menyiapkan Executor untuk Anda - tetapi Anda juga dapat menyesuaikannya sendiri. Misalnya, Anda dapat membagikan Executor latar belakang yang ada dalam aplikasi, membuat Executor thread tunggal untuk memastikan semua pekerjaan latar belakang dijalankan berurutan, atau bahkan menentukan Executor kustom. Untuk menyesuaikan Executor, pastikan Anda menginisialisasi WorkManager secara manual.

Saat mengonfigurasi WorkManager secara manual, Anda dapat menentukan Executor sebagai berikut:

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());

Berikut adalah contoh Worker sederhana yang mendownload konten halaman web 100 kali:

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();
    }

}

Ingat bahwa Worker.doWork() merupakan panggilan sinkron - Anda diharapkan melakukan seluruh pekerjaan latar belakang secara tertutup dan menyelesaikannya sebelum metode ditutup. Jika Anda memanggil API asinkron di doWork() dan menampilkan Result, callback mungkin tidak beroperasi dengan benar. Jika Anda berada dalam situasi ini, pertimbangkan untuk menggunakan ListenableWorker (lihat Threading di ListenableWorker).

Jika Worker yang sedang berjalan dihentikan karena suatu alasan, maka worker akan menerima panggilan ke Worker.onStopped(). Ganti metode ini atau panggil Worker.isStopped() untuk memeriksa kode Anda dan mengosongkan resource, jika perlu. Jika Worker pada contoh di atas dihentikan, worker tersebut mungkin berada di tengah-tengah proses mendownload item dan akan terus mendownload item meskipun telah dihentikan. Untuk mengoptimalkan perilaku ini, Anda bisa melakukannya seperti berikut:

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();
    }
}

Setelah Worker dihentikan, apa pun yang Anda kembalikan dari Worker.doWork() tidak penting lagi; Result akan diabaikan.