Scheduling Background Service Task – start from API 14+

Pada dasarnya terdapat 3 API untuk scheduling task di Background yaitu :

  1. AlarmManager
  2. JobScheduler
  3. WorkManager

Namun, dikarenakan adanya kebijakan dan fitur baru pada API akhir-akhir ini seperti dituliskan pada laman dokumentasi, diantaranya :

  1. Android 6.0 (API level 23) memperkenalkan mode Istirahatkan dan aplikasi standby. Mode Istirahatkan membatasi perilaku aplikasi saat layar nonaktif dan saat perangkat sedang dalam mode standby. Aplikasi standby menempatkan aplikasi yang tidak digunakan dalam status khusus yang akan membatasi akses jaringan, tugas, dan sinkronisasi dari aplikasi.
  2. Android 7.0 (API level 24) membatasi siaran implisit dan memperkenalkan Istirahatkan Kapan Saja.
  3. Android 8.0 (API level 26) selanjutnya membatasi perilaku latar belakang yang terbatas, seperti mendapatkan lokasi di latar belakang dan menghapus wakelock dalam cache.

Beberapa pembaruan ini menyebabkan AlarmManager tidak dapat berjalan sebagaimana semestinya dimulai dari API 23. Sementara JobScheduler yang diperkenalkan sejak API 21 tidak mendukung untuk diimplementasikan pada API dibawah 21. Akan tetapi kita dapat menggunakan WorkManager untuk mengatasi keterbatasan support pada berbagai API ini.

Beberapa fitur utama pada WorkManager :

  1. Kompatibel dengan versi sebelumnya hingga API 14 ( Menggunakan JobScheduler pada perangkat dengan API 23+ dan menggunakan kombinasi BroadcastReceiver + AlarmManager pada perangkat dengan API 14-22)
  2. Menambahkan batasan pekerjaan seperti ketersediaan jaringan atau status pengisian daya
  3. Menjadwalkan tugas satu kali atau berkala asinkron
  4. Memantau dan mengelola tugas terjadwal
  5. Menautkan tugas bersama
  6. Memastikan eksekusi tugas, meskipun aplikasi atau perangkat dimulai ulang
  7. Mematuhi fitur hemat daya seperti mode Istirahatkan

Untuk penggunaanya pertama menambahkan library WorkManager pada build.gradle (pada level Module:app) :

implementation "android.arch.work:work-runtime:1.0.1"

Kemudian buat class utama untuk Worker dari WorkManagernya :

class UploadWorker(
    context: Context,
    workerParameters: WorkerParameters
) : Worker(context, workerParameters) {

    override fun doWork(): Result {
        applicationContext.apply {
            startServiceBy(Intent(this, UploadService::class.java))
        }

        return Result.success()
    }
}

UploadService diatas adalah class service yang akan dijalankan ketika kondisi-kondisi tertentu pada task telah terpenuhi. Dan karena pada API 28 membatasi perilaku latar belakang yang terbatas maka service harus dijalankan di foreground :

fun Context.startServiceBy(service: Intent): ComponentName? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) startForegroundService(service)
    else startService(service)
}

Pada AndroidManifest.xml perlu ditambahkan beberapa permission diantaranya RECEIVE_BOOT_COMPLETED agar WorkManager tetap dapat berjalan di background walaupun device telah mengalami restart.

Lalu yang kedua FOREGROUND_SERVICE, permission untuk dapat menjalankan service di foreground pada Android Oreo keatas (API 28+)

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

Setelah itu class Worker tadi sudah dapat dipanggil untuk scheduling task di background :

        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
        val request = OneTimeWorkRequest.Builder(UploadWorker::class.java)
            .setConstraints(constraints)
            .build()

        WorkManager.getInstance().apply {
            beginUniqueWork(
                WORK_ORDER_UPLOAD_WORKER,
                ExistingWorkPolicy.REPLACE,
                request
            ).enqueue()
        }
  1. Constraint merupakan syarat yang harus terpenuhi terlebih dahulu agar task dapat dijalankan. Selain requirement berupa network, WorkManager juga menyediakan beberapa pilihan requirement lagi diantaranya yaitu ; requiresStorageNotLow() , requiresBatteryNotLow() , requiresCharging() , requiresDeviceIdle() , dan getRequiredNetworkType() seperti diatas namun untuk network requirement ini kita harus menyertakan NetworkType nya juga.
  2. Request dibedakan menjadi 2. Yang pertama adalah OneTimeWorkRequest seperti pada implementasi code diatas untuk menjalankan task hanya sekali saja. Satunya lagi adalah PeriodicWorkRequest yang dapat digunakan untuk menjalankan task secara berulang kali namun interval minimal yang dapat di set adalah 15menit per requestnya sama halnya pada fungsi setPeriodic milik JobScheduler, ini dikarenakan pada Android 6.0 (API level 23) terdapat mode Istirahatkan dan aplikasi standby untuk optimasi penggunaan baterai dari device itu sendiri. Namun fungsi periodic ini dapat tertunda eksekusinya karena seperti yang telah disebutkan pada poin ke-7 Fitur Utama WorkManager yaitu mematuhi fitur hemat daya seperti mode Istirahatkan lagilagi tujuanya adalah untuk optimasi baterai, delay atau penundaan ini seringkali terjadi pada saat device berada pada Doze Mode.

Kesimpulanya adalah WorkManager menyediakan fungsi untuk scheduling task di background. Namun seringkali terdapat delay beberapa detik pada setiap eksekusinya meskipun kondisi dari constraint requirements sudah terpenuhi pada saat itu juga. Tetapi kembali lagi karena tujuanya adalah untuk menjalankan task in background dengan tersedianya execution saat aplikasi di background, ditutup, bahkan ketika device restarted tetap worth it untuk menggunakan WorkManager karena adanya jaminan bahwa task tersebut sudah pasti akan dieksekusi.

Rizky Agung Ramadhan has written 10 articles

2 thoughts on “Scheduling Background Service Task – start from API 14+

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>