Dasar-Dasar Android Kotlin 09.2: WorkManager

Codelab ini adalah bagian dari kursus Dasar-Dasar Android Kotlin. Anda akan mendapatkan manfaat maksimal dari kursus ini jika menyelesaikan codelab secara berurutan. Semua codelab kursus tercantum di halaman landing codelab Dasar-Dasar Android Kotlin.

Pengantar

Sebagian besar aplikasi dunia nyata perlu melakukan tugas latar belakang yang berjalan lama. Misalnya, aplikasi dapat mengupload file ke server, menyinkronkan data dari server dan menyimpannya ke database Room, mengirim log ke server, atau menjalankan operasi yang mahal pada data. Operasi tersebut harus dilakukan di latar belakang, di luar thread UI (thread utama). Tugas latar belakang menggunakan resource perangkat yang terbatas, seperti RAM dan baterai. Hal ini akan memberikan pengalaman yang buruk bagi pengguna jika tidak ditangani dengan benar.

Dalam codelab ini, Anda akan mempelajari cara menggunakan WorkManager untuk menjadwalkan tugas latar belakang dengan cara yang optimal dan efisien. Untuk mempelajari lebih lanjut solusi lain yang tersedia untuk pemrosesan latar belakang di Android, lihat Panduan untuk pemrosesan latar belakang.

Yang harus sudah Anda ketahui

  • Cara menggunakan Komponen Arsitektur Android ViewModel, LiveData, dan Room.
  • Cara melakukan transformasi pada class LiveData.
  • Cara membuat dan meluncurkan coroutine.
  • Cara menggunakan adaptor binding dalam data binding.
  • Cara memuat data yang di-cache menggunakan pola repositori.

Yang akan Anda pelajari

  • Cara membuat Worker, yang mewakili unit kerja.
  • Cara membuat WorkRequest untuk meminta pekerjaan dilakukan.
  • Cara menambahkan batasan ke WorkRequest untuk menentukan cara dan waktu worker harus dijalankan.
  • Cara menggunakan WorkManager untuk menjadwalkan tugas latar belakang.

Yang akan Anda lakukan

  • Buat pekerja untuk menjalankan tugas latar belakang guna mengambil data awal playlist video DevBytes dari jaringan.
  • Jadwalkan pekerja untuk berjalan secara berkala.
  • Tambahkan batasan ke WorkRequest.
  • Jadwalkan WorkRequest berkala yang dijalankan sekali sehari.

Dalam codelab ini, Anda akan mengerjakan aplikasi DevBytes yang Anda kembangkan di codelab sebelumnya. (Jika tidak memiliki aplikasi ini, Anda dapat mendownload kode awal untuk pelajaran ini.)

Aplikasi DevBytes menampilkan daftar video DevByte, yang merupakan tutorial singkat yang dibuat oleh tim hubungan developer Android Google. Video ini memperkenalkan fitur developer dan praktik terbaik untuk pengembangan Android.

Anda meningkatkan pengalaman pengguna di aplikasi dengan melakukan pengambilan data awal video sekali sehari. Hal ini memastikan pengguna mendapatkan konten baru segera setelah mereka membuka aplikasi.

Dalam tugas ini, Anda akan mendownload dan memeriksa kode awal.

Langkah 1: Download dan jalankan aplikasi awal

Anda dapat terus mengerjakan aplikasi DevBytes yang telah Anda buat di codelab sebelumnya (jika Anda memilikinya). Atau, Anda dapat mendownload aplikasi awal.

Dalam tugas ini, Anda akan mendownload dan menjalankan aplikasi awal serta memeriksa kode awal.

  1. Jika Anda belum memiliki aplikasi DevBytes, download kode awal DevBytes untuk codelab ini dari project DevBytesRepository dari GitHub.
  2. Buka zip kode dan buka project di Android Studio.
  3. Hubungkan perangkat pengujian atau emulator Anda ke internet, jika belum terhubung. Buat dan jalankan aplikasi. Aplikasi mengambil daftar video DevByte dari jaringan dan menampilkannya.
  4. Di aplikasi, ketuk video apa pun untuk membukanya di aplikasi YouTube.

Langkah 2: Jelajahi kode

Aplikasi awal dilengkapi dengan banyak kode yang diperkenalkan dalam codelab sebelumnya. Kode awal untuk codelab ini memiliki modul jaringan, antarmuka pengguna, cache offline, dan repositori. Anda dapat berfokus pada penjadwalan tugas latar belakang menggunakan WorkManager.

  1. Di Android Studio, luaskan semua paket.
  2. Jelajahi paket database. Paket ini berisi entity database dan database lokal, yang diimplementasikan menggunakan Room.
  3. Jelajahi paket repository. Paket ini berisi class VideosRepository yang memisahkan lapisan data dari bagian aplikasi lainnya.
  4. Pelajari kode awal lainnya sendiri, dan dengan bantuan codelab sebelumnya.

WorkManager adalah salah satu Komponen Arsitektur Android dan bagian dari Android Jetpack. WorkManager ditujukan untuk pekerjaan latar belakang yang dapat ditangguhkan dan memerlukan eksekusi yang terjamin:

  • Dapat ditangguhkan berarti tugas tidak perlu dijalankan secara langsung. Misalnya, mengirim data analisis ke server atau menyinkronkan database di latar belakang adalah pekerjaan yang dapat ditunda.
  • Eksekusi terjamin berarti tugas akan berjalan meskipun aplikasi ditutup atau perangkat dimulai ulang.

Saat menjalankan pekerjaan latar belakang, WorkManager menangani masalah kompatibilitas dan praktik terbaik untuk kesehatan baterai dan sistem. WorkManager menawarkan kompatibilitas kembali ke API level 14. WorkManager memilih cara yang tepat untuk menjadwalkan tugas latar belakang, bergantung pada level API perangkat. Aplikasi ini dapat menggunakan JobScheduler (di API 23 dan yang lebih tinggi) atau kombinasi AlarmManager dan BroadcastReceiver.

WorkManager juga memungkinkan Anda menetapkan kriteria kapan tugas latar belakang berjalan. Misalnya, Anda mungkin ingin tugas berjalan hanya saat status baterai, status jaringan, atau status pengisian daya memenuhi kriteria tertentu. Anda akan mempelajari cara menyetel batasan nanti dalam codelab ini.

Dalam codelab ini, Anda akan menjadwalkan tugas untuk mengambil playlist video DevBytes dari jaringan setiap hari. Untuk menjadwalkan tugas ini, Anda menggunakan library WorkManager.

  1. Buka file build.gradle (Module:app) dan tambahkan dependensi WorkManager ke project.

    Jika Anda menggunakan versi terbaru library, aplikasi solusi akan dikompilasi seperti yang diharapkan. Jika tidak, coba selesaikan masalahnya, atau kembali ke versi pustaka yang ditampilkan di bawah.
// WorkManager dependency
def work_version = "1.0.1"
implementation "android.arch.work:work-runtime-ktx:$work_version"
  1. Sinkronkan project Anda dan pastikan tidak ada error kompilasi.

Sebelum menambahkan kode ke project, pahami class berikut di library WorkManager:

  • Worker
    Di class ini, Anda menentukan pekerjaan sebenarnya (tugas) yang akan dijalankan di latar belakang. Anda memperluas class ini dan mengganti metode doWork(). Metode doWork() adalah tempat Anda menempatkan kode yang akan dijalankan di latar belakang, seperti menyinkronkan data dengan server atau memproses gambar. Anda akan menerapkan Worker dalam tugas ini.
  • WorkRequest
    Class ini merepresentasikan permintaan untuk menjalankan pekerja di latar belakang. Gunakan WorkRequest untuk mengonfigurasi cara dan waktu menjalankan tugas pekerja, dengan bantuan Constraints seperti perangkat dicolokkan atau Wi-Fi terhubung. Anda akan menerapkan WorkRequest di tugas selanjutnya.
  • WorkManager
    Kelas ini menjadwalkan dan menjalankan WorkRequest Anda. WorkManager menjadwalkan permintaan kerja dengan cara menyebarkan beban pada resource sistem, sekaligus memenuhi batasan yang Anda tetapkan. Anda akan menerapkan WorkManager di tugas selanjutnya.

Langkah 1: Buat pekerja

Dalam tugas ini, Anda akan menambahkan Worker untuk melakukan pengambilan data awal playlist video DevBytes di latar belakang.

  1. Di dalam paket devbyteviewer, buat paket baru bernama work.
  2. Di dalam paket work, buat class Kotlin baru bernama RefreshDataWorker.
  3. Perluas class RefreshDataWorker dari class CoroutineWorker. Teruskan context dan WorkerParameters sebagai parameter konstruktor.
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {
}
  1. Untuk mengatasi error class abstrak, ganti metode doWork() di dalam class RefreshDataWorker.
override suspend fun doWork(): Result {
  return Result.success()
}

Fungsi penangguhan adalah fungsi yang dapat dijeda dan dilanjutkan nanti. Fungsi penangguhan dapat menjalankan operasi yang berjalan lama dan menunggu hingga selesai tanpa memblokir thread utama.

Langkah 2: Implementasikan doWork()

Metode doWork() di dalam class Worker dipanggil di thread latar belakang. Metode ini melakukan pekerjaan secara sinkron, dan harus menampilkan objek ListenableWorker.Result. Sistem Android memberi Worker waktu maksimum 10 menit untuk menyelesaikan eksekusinya dan menampilkan objek ListenableWorker.Result. Setelah waktu ini berakhir, sistem akan menghentikan Worker secara paksa.

Untuk membuat objek ListenableWorker.Result, panggil salah satu metode statis berikut untuk menunjukkan status penyelesaian pekerjaan latar belakang:

Dalam tugas ini, Anda akan mengimplementasikan metode doWork() untuk mengambil playlist video DevBytes dari jaringan. Anda dapat menggunakan kembali metode yang ada di class VideosRepository untuk mengambil data dari jaringan.

  1. Di class RefreshDataWorker, di dalam doWork(), buat dan buat instance objek VideosDatabase dan objek VideosRepository.
override suspend fun doWork(): Result {
   val database = getDatabase(applicationContext)
   val repository = VideosRepository(database)

   return Result.success()
}
  1. Di class RefreshDataWorker, di dalam doWork(), di atas pernyataan return, panggil metode refreshVideos() di dalam blok try. Tambahkan log untuk melacak kapan pekerja dijalankan.
try {
   repository.refreshVideos( )
   Timber.d("Work request for sync is run")
   } catch (e: HttpException) {
   return Result.retry()
}

Untuk mengatasi error "Referensi yang belum terselesaikan", impor retrofit2.HttpException.

  1. Berikut adalah class RefreshDataWorker lengkap untuk referensi Anda:
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {

   override suspend fun doWork(): Result {
       val database = getDatabase(applicationContext)
       val repository = VideosRepository(database)
       try {
           repository.refreshVideos()
       } catch (e: HttpException) {
           return Result.retry()
       }
       return Result.success()
   }
}

Worker menentukan unit kerja, dan WorkRequest menentukan cara dan waktu untuk menjalankan pekerjaan. Ada dua penerapan konkret class WorkRequest:

  • Class OneTimeWorkRequest ditujukan untuk tugas satu kali. (Tugas sekali saja hanya terjadi satu kali.)
  • Class PeriodicWorkRequest ditujukan untuk pekerjaan berkala, pekerjaan yang berulang secara berkala.

Tugas dapat bersifat sekali waktu atau berkala, jadi pilih kelas yang sesuai. Untuk mengetahui informasi selengkapnya tentang cara menjadwalkan pekerjaan berulang, lihat dokumentasi pekerjaan berulang.

Dalam tugas ini, Anda akan menentukan dan menjadwalkan WorkRequest untuk menjalankan pekerja yang Anda buat di tugas sebelumnya.

Langkah 1: Siapkan pekerjaan berulang

Dalam aplikasi Android, class Application adalah class dasar yang berisi semua komponen lain, seperti aktivitas dan layanan. Saat proses untuk aplikasi atau paket Anda dibuat, class Application (atau subclass Application) dibuat instance-nya sebelum class lainnya.

Dalam aplikasi contoh ini, class DevByteApplication adalah subclass dari class Application. Class DevByteApplication adalah tempat yang tepat untuk menjadwalkan WorkManager.

  1. Di class DevByteApplication, buat metode bernama setupRecurringWork() untuk menyiapkan pekerjaan latar belakang berulang.
/**
* Setup WorkManager background job to 'fetch' new network data daily.
*/
private fun setupRecurringWork() {
}
  1. Di dalam metode setupRecurringWork(), buat dan lakukan inisialisasi permintaan tugas berkala untuk dijalankan sekali sehari, menggunakan metode PeriodicWorkRequestBuilder(). Teruskan class RefreshDataWorker yang Anda buat di tugas sebelumnya. Teruskan interval pengulangan 1 dengan satuan waktu TimeUnit.DAYS.
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .build()

Untuk mengatasi error, impor java.util.concurrent.TimeUnit.

Langkah 2: Jadwalkan WorkRequest dengan WorkManager

Setelah menentukan WorkRequest, Anda dapat menjadwalkannya dengan WorkManager menggunakan metode enqueueUniquePeriodicWork(). Metode ini memungkinkan Anda menambahkan PeriodicWorkRequest bernama unik ke antrean, dengan hanya satu PeriodicWorkRequest dengan nama tertentu yang dapat aktif dalam satu waktu.

Misalnya, Anda mungkin hanya ingin satu operasi sinkronisasi yang aktif. Jika satu operasi sinkronisasi tertunda, Anda dapat memilih untuk membiarkannya berjalan atau menggantinya dengan tugas baru, menggunakan ExistingPeriodicWorkPolicy.

Untuk mempelajari lebih lanjut cara menjadwalkan WorkRequest, lihat dokumentasi WorkManager.

  1. Di class RefreshDataWorker, di awal class, tambahkan objek pendamping. Tentukan nama pekerja untuk mengidentifikasi pekerja ini secara unik.
companion object {
   const val WORK_NAME = "com.example.android.devbyteviewer.work.RefreshDataWorker"
}
  1. Di class DevByteApplication, di akhir metode setupRecurringWork(), jadwalkan pekerjaan menggunakan metode enqueueUniquePeriodicWork(). Teruskan enum KEEP untuk ExistingPeriodicWorkPolicy. Teruskan repeatingRequest sebagai parameter PeriodicWorkRequest.
WorkManager.getInstance().enqueueUniquePeriodicWork(
       RefreshDataWorker.WORK_NAME,
       ExistingPeriodicWorkPolicy.KEEP,
       repeatingRequest)

Jika ada tugas tertunda (belum selesai) dengan nama yang sama, parameter ExistingPeriodicWorkPolicy.KEEP akan membuat WorkManager mempertahankan tugas berkala sebelumnya dan membuang permintaan tugas baru.

  1. Di awal class DevByteApplication, buat objek CoroutineScope. Teruskan Dispatchers.Default sebagai parameter konstruktor.
private val applicationScope = CoroutineScope(Dispatchers.Default)
  1. Di class DevByteApplication, tambahkan metode baru bernama delayedInit() untuk memulai coroutine.
private fun delayedInit() {
   applicationScope.launch {
   }
}
  1. Di dalam metode delayedInit(), panggil setupRecurringWork().
  2. Pindahkan inisialisasi Timber dari metode onCreate() ke metode delayedInit().
private fun delayedInit() {
   applicationScope.launch {
       Timber.plant(Timber.DebugTree())
       setupRecurringWork()
   }
}
  1. Di class DevByteApplication, di akhir metode onCreate(), tambahkan panggilan ke metode delayedInit().
override fun onCreate() {
   super.onCreate()
   delayedInit()
}
  1. Buka panel Logcat di bagian bawah jendela Android Studio. Filter di RefreshDataWorker.
  2. Jalankan aplikasi. WorkManager akan segera menjadwalkan pekerjaan berulang Anda.

    Di panel Logcat, perhatikan pernyataan log yang menunjukkan bahwa permintaan tugas dijadwalkan, lalu berhasil dijalankan.
D/RefreshDataWorker: Work request for sync is run
I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]

Log WM-WorkerWrapper ditampilkan dari library WorkManager, sehingga Anda tidak dapat mengubah pesan log ini.

Langkah 3: (Opsional) Jadwalkan WorkRequest untuk interval minimum

Pada langkah ini, Anda mengurangi interval waktu dari 1 hari menjadi 15 menit. Anda melakukan ini agar dapat melihat cara kerja log untuk permintaan tugas berkala.

  1. Di class DevByteApplication, di dalam metode setupRecurringWork(), jadikan definisi repeatingRequest saat ini sebagai komentar. Tambahkan permintaan kerja baru dengan interval pengulangan berkala 15 menit.
// val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
//        .build()
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(15, TimeUnit.MINUTES)
       .build()
  1. Buka panel Logcat di Android Studio dan filter di RefreshDataWorker. Untuk menghapus log sebelumnya, klik ikon Clear logcat .
  2. Jalankan aplikasi, dan WorkManager akan segera menjadwalkan pekerjaan berulang Anda. Di panel Logcat, perhatikan log—permintaan pekerjaan dijalankan sekali setiap 15 menit. Tunggu 15 menit untuk melihat kumpulan log permintaan tugas lainnya. Anda dapat membiarkan aplikasi berjalan atau menutupnya; pengelola tugas akan tetap berjalan.

    Perhatikan bahwa interval terkadang kurang dari 15 menit, dan terkadang lebih dari 15 menit. (Waktu yang tepat tunduk pada pengoptimalan baterai OS.)
12:44:40 D/RefreshDataWorker: Work request for sync is run
12:44:40 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
12:59:24 D/RefreshDataWorker: Work request for sync is run
12:59:24 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
13:15:03 D/RefreshDataWorker: Work request for sync is run
13:15:03 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
13:29:22 D/RefreshDataWorker: Work request for sync is run
13:29:22 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
13:44:26 D/RefreshDataWorker: Work request for sync is run
13:44:26 I/WM-WorkerWrapper: Worker result SUCCESS for Work
 

Selamat! Anda telah membuat pekerja dan menjadwalkan permintaan pekerjaan dengan WorkManager. Namun, ada masalah: Anda tidak menentukan batasan apa pun. WorkManager akan menjadwalkan tugas sekali sehari, meskipun daya baterai perangkat lemah, perangkat dalam mode tidur, atau tidak memiliki koneksi jaringan. Hal ini akan memengaruhi baterai dan performa perangkat serta dapat mengakibatkan pengalaman pengguna yang buruk.

Pada tugas berikutnya, Anda akan mengatasi masalah ini dengan menambahkan batasan.

Pada tugas sebelumnya, Anda menggunakan WorkManager untuk menjadwalkan permintaan kerja. Dalam tugas ini, Anda menambahkan kriteria untuk kapan harus menjalankan pekerjaan.

Saat menentukan WorkRequest, Anda dapat menentukan batasan waktu berjalannya Worker. Contohnya, Anda ingin menetapkan bahwa tugas hanya berjalan ketika perangkat sedang tidak melakukan aktivitas, atau hanya ketika perangkat dicolokkan dan dihubungkan ke Wi-Fi. Anda juga dapat menentukan kebijakan mundur untuk mencoba ulang tugas. Batasan yang didukung adalah metode set di Constraints.Builder. Untuk mempelajari lebih lanjut, lihat Menentukan Permintaan Pekerjaan Anda.

Langkah 1: Tambahkan objek Constraints dan tetapkan satu batasan

Pada langkah ini, Anda akan membuat objek Constraints dan menetapkan satu batasan pada objek, yaitu batasan jenis jaringan. (Akan lebih mudah untuk melihat log hanya dengan satu batasan. Pada langkah selanjutnya, Anda akan menambahkan batasan lainnya.)

  1. Di class DevByteApplication, di awal setupRecurringWork(), tentukan val dari jenis Constraints. Gunakan metode Constraints.Builder().
val constraints = Constraints.Builder()

Untuk mengatasi error, impor androidx.work.Constraints.

  1. Gunakan metode setRequiredNetworkType() untuk menambahkan batasan jenis jaringan ke objek constraints. Gunakan enum UNMETERED agar permintaan pekerjaan hanya berjalan saat perangkat berada di jaringan tidak berbayar.
.setRequiredNetworkType(NetworkType.UNMETERED)
  1. Gunakan metode build() untuk membuat batasan dari builder.
val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .build()

Sekarang Anda perlu menyetel objek Constraints yang baru dibuat ke permintaan kerja.

  1. Di class DevByteApplication, di dalam metode setupRecurringWork(), tetapkan objek Constraints ke permintaan pekerjaan berkala, repeatingRequest. Untuk menetapkan batasan, tambahkan metode setConstraints() di atas panggilan metode build().
       val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(15, TimeUnit.MINUTES)
               .setConstraints(constraints)
               .build()

Langkah 2: Jalankan aplikasi dan perhatikan log

Pada langkah ini, Anda menjalankan aplikasi dan melihat permintaan kerja yang dibatasi berjalan di latar belakang pada interval tertentu.

  1. Uninstal aplikasi dari perangkat atau emulator untuk membatalkan tugas yang dijadwalkan sebelumnya.
  2. Buka panel Logcat di Android Studio. Di panel Logcat, hapus log sebelumnya dengan mengklik ikon Clear logcat di sebelah kiri. Filter di work.
  3. Nonaktifkan Wi-Fi di perangkat atau emulator, sehingga Anda dapat melihat cara kerja batasan. Kode saat ini hanya menetapkan satu batasan, yang menunjukkan bahwa permintaan hanya boleh berjalan di jaringan tanpa kuota. Karena Wi-Fi nonaktif, perangkat tidak terhubung ke jaringan, baik berbayar maupun tidak berbayar. Oleh karena itu, batasan ini tidak akan terpenuhi.
  4. Jalankan aplikasi dan perhatikan panel Logcat. WorkManager menjadwalkan tugas latar belakang dengan segera. Karena batasan jaringan tidak terpenuhi, tugas tidak dijalankan.
11:31:44 D/DevByteApplication: Periodic Work request for sync is scheduled
  1. Aktifkan Wi-Fi di perangkat atau emulator dan amati panel Logcat. Sekarang, tugas latar belakang terjadwal dijalankan kira-kira setiap 15 menit, selama batasan jaringan terpenuhi.
11:31:44 D/DevByteApplication: Periodic Work request for sync is scheduled
11:31:47 D/RefreshDataWorker: Work request for sync is run
11:31:47 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]
11:46:45 D/RefreshDataWorker: Work request for sync is run
11:46:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:03:05 D/RefreshDataWorker: Work request for sync is run
12:03:05 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:16:45 D/RefreshDataWorker: Work request for sync is run
12:16:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:31:45 D/RefreshDataWorker: Work request for sync is run
12:31:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:47:05 D/RefreshDataWorker: Work request for sync is run
12:47:05 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
13:01:45 D/RefreshDataWorker: Work request for sync is run
13:01:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]

Langkah 3: Tambahkan batasan lainnya

Pada langkah ini, Anda menambahkan batasan berikut ke PeriodicWorkRequest:

  • Daya baterai tidak lemah.
  • Pengisian daya perangkat.
  • Perangkat dalam kondisi tidak ada aktivitas; hanya tersedia di level API 23 (Android M) dan yang lebih tinggi.

Terapkan kode berikut di class DevByteApplication.

  1. Di class DevByteApplication, di dalam metode setupRecurringWork(), tunjukkan bahwa permintaan pekerjaan hanya boleh berjalan jika baterai tidak lemah. Tambahkan batasan sebelum panggilan metode build(), dan gunakan metode setRequiresBatteryNotLow().
.setRequiresBatteryNotLow(true)
  1. Perbarui permintaan tugas agar hanya berjalan saat perangkat sedang mengisi daya. Tambahkan batasan sebelum panggilan metode build(), dan gunakan metode setRequiresCharging().
.setRequiresCharging(true)
  1. Perbarui permintaan kerja agar hanya berjalan saat perangkat tidak ada aktivitas. Tambahkan batasan sebelum panggilan metode build(), dan gunakan metode setRequiresDeviceIdle(). Batasan ini menjalankan permintaan tugas hanya saat pengguna tidak sedang menggunakan perangkat secara aktif. Fitur ini hanya tersedia di Android 6.0 (Marshmallow) dan yang lebih tinggi, jadi tambahkan kondisi untuk SDK versi M dan yang lebih tinggi.
.apply {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       setRequiresDeviceIdle(true)
   }
}

Berikut definisi lengkap objek constraints.

val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresBatteryNotLow(true)
       .setRequiresCharging(true)
       .apply {
           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
               setRequiresDeviceIdle(true)
           }
       }
       .build()
  1. Dalam metode setupRecurringWork(), ubah kembali interval permintaan menjadi sekali sehari.
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .setConstraints(constraints)
       .build()

Berikut adalah penerapan lengkap metode setupRecurringWork(), dengan log sehingga Anda dapat melacak kapan permintaan pekerjaan berkala dijadwalkan.

private fun setupRecurringWork() {

       val constraints = Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .setRequiresBatteryNotLow(true)
               .setRequiresCharging(true)
               .apply {
                   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                       setRequiresDeviceIdle(true)
                   }
               }
               .build()
       val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
               .setConstraints(constraints)
               .build()
       
       Timber.d("Periodic Work request for sync is scheduled")
       WorkManager.getInstance().enqueueUniquePeriodicWork(
               RefreshDataWorker.WORK_NAME,
               ExistingPeriodicWorkPolicy.KEEP,
               repeatingRequest)
   }
  1. Untuk menghapus permintaan kerja yang dijadwalkan sebelumnya, uninstal aplikasi DevBytes dari perangkat atau emulator Anda.
  2. Jalankan aplikasi, dan WorkManager akan segera menjadwalkan permintaan pekerjaan. Permintaan pekerjaan berjalan sekali sehari, saat semua batasan terpenuhi.
  3. Permintaan kerja ini akan berjalan di latar belakang selama aplikasi diinstal, meskipun aplikasi tidak berjalan. Oleh karena itu, Anda harus meng-uninstal aplikasi dari ponsel.

Bagus! Anda telah menerapkan dan menjadwalkan permintaan tugas yang hemat baterai untuk pengambilan awal video harian di aplikasi DevBytes. WorkManager akan menjadwalkan dan menjalankan tugas, serta mengoptimalkan resource sistem. Pengguna Anda dan baterai mereka akan sangat senang.

Project Android Studio: DevBytesWorkManager.

  • WorkManager API memudahkan penjadwalan tugas-tugas asinkron yang dapat ditangguhkan dan harus berjalan tanpa masalah.
  • Sebagian besar aplikasi dunia nyata perlu melakukan tugas latar belakang yang berjalan lama. Untuk menjadwalkan tugas latar belakang dengan cara yang optimal dan efisien, gunakan WorkManager.
  • Class utama di library WorkManager adalah Worker, WorkRequest, dan WorkManager.
  • Class Worker mewakili unit kerja. Untuk mengimplementasikan tugas latar belakang, perluas class Worker dan ganti metode doWork().
  • Class WorkRequest mewakili permintaan untuk melakukan unit pekerjaan. WorkRequest adalah class dasar untuk menentukan parameter bagi tugas yang Anda jadwalkan di WorkManager.
  • Ada dua implementasi konkret dari class WorkRequest: OneTimeWorkRequest untuk tugas satu kali, dan PeriodicWorkRequest untuk permintaan pekerjaan berkala.
  • Saat menentukan WorkRequest, Anda dapat menentukan Constraints yang menunjukkan kapan Worker harus dijalankan. Batasan mencakup hal-hal seperti apakah perangkat dicolokkan, apakah perangkat menganggur, atau apakah Wi-Fi terhubung.
  • Untuk menambahkan batasan ke WorkRequest, gunakan metode set yang tercantum dalam dokumentasi Constraints.Builder. Misalnya, untuk menunjukkan bahwa WorkRequest tidak boleh berjalan jika baterai perangkat lemah, gunakan metode set setRequiresBatteryNotLow().
  • Setelah Anda menentukan WorkRequest, serahkan tugas ke sistem Android. Untuk melakukannya, jadwalkan tugas menggunakan salah satu metode WorkManager enqueue.
  • Waktu pasti eksekusi Worker bergantung pada batasan yang digunakan dalam WorkRequest, dan pada pengoptimalan sistem. WorkManager dirancang untuk memberikan perilaku terbaik dalam batasan ini.

Kursus Udacity:

Dokumentasi developer Android:

Lainnya:

Bagian ini mencantumkan kemungkinan tugas pekerjaan rumah untuk siswa yang mengerjakan codelab ini sebagai bagian dari kursus yang dipimpin oleh instruktur. Instruktur menentukan hal berikut:

  • Memberikan pekerjaan rumah jika diperlukan.
  • Memberi tahu siswa cara mengirimkan tugas pekerjaan rumah.
  • Memberi nilai tugas pekerjaan rumah.

Instruktur bisa menggunakan saran ini sesuai kebutuhan, dan bebas menugaskan pekerjaan rumah lain yang dirasa cocok.

Jika Anda menyelesaikan codelab ini sendiri, gunakan tugas pekerjaan rumah ini untuk menguji pengetahuan Anda.

Pertanyaan 1

Apa yang merupakan penerapan konkret class WorkRequest?

OneTimeWorkPeriodicRequest

OneTimeWorkRequest dan PeriodicWorkRequest

OneTimeWorkRequest dan RecurringWorkRequest

OneTimeOffWorkRequest dan RecurringWorkRequest

Pertanyaan 2

Manakah dari class berikut yang digunakan WorkManager untuk menjadwalkan tugas latar belakang pada API 23 dan yang lebih baru?

▢ Hanya JobScheduler

BroadcastReceiver dan AlarmManager

AlarmManager dan JobScheduler

Scheduler dan BroadcastReceiver

Pertanyaan 3

API mana yang Anda gunakan untuk menambahkan batasan ke WorkRequest?

setConstraints()

addConstraints()

setConstraint()

addConstraintsToWorkRequest()

Lanjutkan ke pelajaran berikutnya: 10.1 Gaya dan tema

Untuk link ke codelab lain dalam kursus ini, lihat halaman landing codelab Dasar-Dasar Android Kotlin.