Setiap kali berjalan di latar belakang, aplikasi akan menggunakan beberapa resource perangkat yang terbatas, seperti RAM. Hal ini dapat menyebabkan gangguan pengalaman pengguna, terutama jika pengguna menggunakan aplikasi yang menggunakan banyak resource, seperti bermain game atau menonton video. Untuk meningkatkan pengalaman pengguna, Android 8.0 (API level 26) mengenakan batasan terkait tindakan yang dapat dilakukan aplikasi saat berjalan di latar belakang. Dokumen ini menjelaskan perubahan pada sistem operasi, dan cara mengupdate aplikasi agar berfungsi dengan baik dengan batasan baru ini.
Ringkasan
Banyak aplikasi dan layanan Android yang bisa dijalankan secara bersamaan. Misalnya, pengguna dapat memainkan game di satu jendela sambil menjelajahi web di jendela lain, dan menggunakan aplikasi ketiga untuk memainkan musik. Semakin banyak aplikasi yang berjalan sekaligus, semakin banyak beban yang diberikan pada sistem. Jika aplikasi atau layanan tambahan berjalan di latar belakang, tindakan ini akan menempatkan beban tambahan pada sistem, yang dapat mengakibatkan pengalaman pengguna yang buruk; misalnya, aplikasi musik mungkin tiba-tiba dimatikan.
Untuk mengurangi kemungkinan terjadinya masalah ini, Android 8.0 menerapkan batasan pada hal yang dapat dilakukan aplikasi selagi pengguna tidak berinteraksi secara langsung dengan aplikasi. Aplikasi dibatasi dengan dua cara:
Batasan Layanan Latar Belakang: Saat aplikasi tidak ada aktivitas, ada batasan pada penggunaan layanan latar belakangnya. Hal ini tidak berlaku untuk layanan latar depan, yang lebih terlihat oleh pengguna.
Batasan Siaran: Dengan pengecualian terbatas, aplikasi tidak dapat menggunakan manifesnya untuk mendaftar siaran implisit. Mereka masih dapat mendaftar ke siaran ini saat runtime, serta dapat menggunakan manifes untuk mendaftar ke siaran eksplisit dan siaran yang ditargetkan secara khusus pada aplikasi mereka.
Pada umumnya, aplikasi dapat mengatasi batasan ini dengan menggunakan
tugas JobScheduler
. Pendekatan ini memungkinkan aplikasi mengatur untuk
melakukan pekerjaan saat aplikasi tidak berjalan secara aktif, tetapi tetap memberi sistem
keleluasaan untuk menjadwalkan tugas ini dengan cara yang tidak memengaruhi pengalaman
pengguna. Android 8.0 menawarkan beberapa peningkatan pada JobScheduler
yang mempermudah penggantian layanan dan
penerima siaran dengan tugas terjadwal; untuk informasi selengkapnya, lihat
peningkatan JobScheduler.
Batasan Layanan Latar Belakang
Layanan yang berjalan di latar belakang dapat menghabiskan resource perangkat, yang berpotensi mengakibatkan pengalaman pengguna yang lebih buruk. Untuk mengurangi masalah ini, sistem menerapkan sejumlah batasan pada layanan.
Sistem membedakan antara aplikasi latar depan dan latar belakang. (Definisi latar belakang untuk tujuan batasan layanan berbeda dengan definisi yang digunakan oleh pengelolaan memori; aplikasi mungkin berada di latar belakang dalam kaitannya dengan pengelolaan memori, tetapi berada di latar depan sehubungan dengan kemampuannya untuk meluncurkan layanan.) Aplikasi dianggap berada di latar depan jika salah satu dari pernyataan berikut terpenuhi:
- Aplikasi memiliki aktivitas yang terlihat, baik yang telah dimulai maupun yang dihentikan sementara.
- Aplikasi memiliki layanan latar depan.
- Aplikasi latar depan yang lain terhubung ke aplikasi tersebut, baik melalui binding ke salah satu
layanannya maupun melalui salah satu penyedia kontennya. Misalnya,
aplikasi berada di latar depan jika aplikasi lain terikat ke:
- IME
- Layanan wallpaper
- Pemroses notifikasi
- Layanan suara atau teks
Jika tidak satu pun dari kondisi tersebut yang benar, aplikasi akan dianggap berada di latar belakang.
Saat berada di latar depan, aplikasi dapat membuat dan menjalankan layanan latar depan dan
latar belakang dengan bebas. Saat beralih ke latar belakang, aplikasi memiliki
periode beberapa menit yang tetap diizinkan untuk membuat dan menggunakan
layanan. Di akhir jendela tersebut, aplikasi akan dianggap tidak ada aktivitas. Pada
saat ini, sistem menghentikan layanan latar belakang aplikasi, seolah-olah aplikasi
telah memanggil metode Service.stopSelf()
layanan.
Dalam keadaan tertentu, aplikasi latar belakang ditempatkan di daftar yang diizinkan sementara selama beberapa menit. Meskipun berada dalam daftar yang diizinkan, aplikasi dapat meluncurkan layanan tanpa batasan, dan layanan latar belakangnya boleh dijalankan. Aplikasi ditempatkan dalam daftar yang diizinkan saat menangani tugas yang terlihat oleh pengguna, seperti:
- Menangani pesan Firebase Cloud Messaging (FCM) berprioritas tinggi.
- Menerima suatu siaran, misalnya pesan SMS/MMS.
- Mengeksekusi
PendingIntent
dari notifikasi. - Memulai
VpnService
sebelum aplikasi VPN mempromosikan dirinya sendiri ke latar depan.
Umumnya, aplikasi Anda dapat mengganti layanan latar belakang dengan tugas JobScheduler
.
Misalnya, CoolPhotoApp perlu memeriksa
apakah pengguna telah menerima foto yang dibagikan dari teman, meskipun aplikasi tidak
berjalan di latar depan. Sebelumnya, aplikasi telah menggunakan layanan latar belakang
yang diperiksa dengan penyimpanan cloud aplikasi. Untuk bermigrasi ke Android 8.0 (API level 26),
developer mengganti layanan latar belakang dengan tugas terjadwal, yang
diluncurkan secara berkala, mengkueri server, lalu keluar.
Sebelum Android 8.0, biasanya cara untuk membuat layanan latar depan
adalah membuat layanan latar belakang, lalu mempromosikan layanan tersebut ke latar depan.
Dengan Android 8.0, terdapat detail; sistem tidak mengizinkan aplikasi
latar belakang membuat layanan latar belakang. Karena alasan ini, Android 8.0 memperkenalkan
metode baru startForegroundService()
untuk memulai layanan baru di
latar depan. Setelah sistem membuat
layanan, aplikasi memiliki waktu lima detik untuk memanggil metode [startForeground()
](/reference/android/app/Service#startForeground(int, android.app.Notification) layanan baru untuk menampilkan notifikasi
yang terlihat oleh pengguna dari layanan baru tersebut. Jika aplikasi tidak memanggil startForeground()
dalam
batas waktu, sistem akan menghentikan layanan dan mendeklarasikan aplikasi sebagai
ANR.
Batasan Siaran
Jika aplikasi mendaftar untuk menerima siaran, penerima aplikasi akan menggunakan resource setiap kali siaran dikirim. Hal ini dapat menyebabkan masalah jika terlalu banyak aplikasi yang mendaftar untuk menerima siaran berdasarkan peristiwa sistem; peristiwa sistem yang memicu siaran dapat menyebabkan semua aplikasi tersebut menggunakan resource dalam urutan cepat, sehingga mengganggu pengalaman pengguna. Untuk mengurangi masalah ini, Android 7.0 (API level 24) menerapkan batasan pada siaran, seperti yang dijelaskan dalam Pengoptimalan Latar Belakang. Android 8.0 (API level 26) membuat pembatasan-pembatasan ini lebih ketat.
- Aplikasi yang menargetkan Android 8.0 atau yang lebih tinggi tidak dapat lagi mendaftarkan penerima
siaran untuk siaran implisit dalam manifesnya, kecuali siaran tersebut
dibatasi khusus untuk aplikasi tersebut. Siaran implisit adalah
siaran yang tidak menargetkan komponen tertentu dalam aplikasi. Misalnya,
ACTION_PACKAGE_REPLACED
dikirim ke semua pemroses terdaftar di semua aplikasi, yang memberi tahu mereka bahwa beberapa paket di perangkat telah diganti. Karena bersifat implisit, siaran tidak akan dikirimkan ke penerima yang terdaftar di manifes dalam aplikasi yang menargetkan Android 8.0 atau yang lebih tinggi.ACTION_MY_PACKAGE_REPLACED
juga merupakan siaran implisit, tetapi karena dikirim hanya ke aplikasi yang paketnya telah diganti, akan dikirimkan ke penerima yang terdaftar di manifes. - Aplikasi tetap bisa mendaftar untuk mendapatkan siaran eksplisit dalam manifesnya.
- Aplikasi dapat menggunakan
Context.registerReceiver()
pada runtime untuk mendaftarkan penerima siaran apa pun, baik implisit maupun eksplisit. - Siaran yang memerlukan izin tanda tangan dikecualikan dari pembatasan ini karena siaran ini hanya dikirim ke aplikasi yang ditandatangani dengan sertifikat yang sama, bukan ke semua aplikasi pada perangkat.
Dalam banyak kasus, aplikasi yang sebelumnya terdaftar untuk siaran implisit bisa
mendapatkan fungsi serupa dengan menggunakan tugas JobScheduler
.
Misalnya, aplikasi foto sosial mungkin perlu melakukan pembersihan pada datanya dari
waktu ke waktu, dan lebih suka melakukannya saat perangkat terhubung ke pengisi daya.
Sebelumnya, aplikasi telah mendaftarkan penerima ACTION_POWER_CONNECTED
dalam manifesnya; saat aplikasi
menerima siaran tersebut, aplikasi akan memeriksa apakah pembersihan perlu dilakukan. Untuk
bermigrasi ke Android 8.0 atau yang lebih tinggi, aplikasi akan menghapus penerima tersebut dari
manifesnya. Sebagai gantinya, aplikasi akan menjadwalkan tugas pembersihan yang berjalan saat perangkat
tidak ada aktivitas dan mengisi daya.
Panduan Migrasi
Secara default, perubahan ini hanya memengaruhi aplikasi yang menargetkan Android 8.0 (API level 26) atau yang lebih tinggi. Namun, pengguna dapat mengaktifkan pembatasan ini untuk aplikasi apa pun dari layar Setelan, meskipun aplikasi menargetkan API level yang lebih rendah dari 26. Anda mungkin perlu mengupdate aplikasi untuk mematuhi batasan baru ini.
Periksa untuk mengetahui cara aplikasi Anda menggunakan layanan. Jika aplikasi Anda mengandalkan layanan yang berjalan di latar belakang saat tidak ada aktivitas, Anda harus menggantinya. Solusi yang memungkinkan antara lain:
- Jika aplikasi Anda perlu membuat layanan latar depan saat aplikasi berada di
latar belakang, gunakan
metode
startForegroundService()
, bukanstartService()
. - Jika layanan terlihat oleh pengguna, maka jadikan layanan latar depan. Misalnya, layanan yang memutar audio harus selalu berupa layanan latar depan.
Buat layanan menggunakan metode
startForegroundService()
, bukanstartService()
. - Temukan cara untuk menduplikasi fungsi layanan dengan tugas terjadwal. Jika layanan tidak langsung melakukan sesuatu yang terlihat oleh pengguna, Anda biasanya dapat menggunakan tugas terjadwal.
- Gunakan FCM untuk mengaktifkan aplikasi Anda secara selektif saat terjadi peristiwa jaringan, bukan polling di latar belakang.
- Tangguhkan pekerjaan latar belakang hingga aplikasi berada di latar depan dengan sendirinya.
Tinjau penerima siaran yang ditentukan dalam manifes aplikasi Anda. Jika manifes Anda mendeklarasikan penerima siaran implisit yang terpengaruh, Anda harus menggantinya. Solusi yang memungkinkan antara lain:
- Buat penerima saat runtime dengan memanggil
Context.registerReceiver()
, bukan mendeklarasikan penerima dalam manifes. - Gunakan tugas terjadwal untuk memeriksa kondisi yang akan memicu siaran implisit.