Batas Eksekusi Latar Belakang

Setiap kali berjalan di latar belakang, aplikasi akan menggunakan beberapa resource perangkat yang terbatas, seperti RAM. Hal ini dapat mengganggu 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 hal 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 bermain game di satu jendela sambil menjelajahi web di jendela lain, dan menggunakan aplikasi ketiga untuk memutar 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 pemuatan 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 penggunaan layanan latar belakang. 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. Aplikasi masih dapat mendaftar ke siaran ini pada runtime, dan dapat menggunakan manifes untuk mendaftar ke siaran eksplisit dan siaran yang ditargetkan secara khusus di 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 kelonggaran untuk menjadwalkan tugas ini dengan cara yang tidak memengaruhi pengalaman pengguna. Android 8.0 menawarkan beberapa peningkatan pada JobScheduler yang memudahkan 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 dan berpotensi mengakibatkan pengalaman pengguna yang lebih buruk. Untuk mengurangi masalah ini, sistem menerapkan sejumlah batasan atas layanan.

Sistem membedakan antara aplikasi latar depan dan latar belakang. (Definisi latar belakang untuk tujuan pembatasan layanan berbeda dengan definisi yang digunakan oleh pengelolaan memori; aplikasi mungkin berada di latar belakang sehubungan 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 penggunaan salah satu penyedia kontennya. Misalnya, aplikasi berada di latar depan jika aplikasi lain mengikat:
    • 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 jangka waktu beberapa menit yang mengizinkan aplikasi 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 dalam daftar yang diizinkan sementara selama beberapa menit. Meskipun berada dalam daftar yang diizinkan, aplikasi dapat meluncurkan layanan tanpa batasan, dan layanan latar belakangnya diizinkan untuk dijalankan. Aplikasi ditempatkan di daftar yang diizinkan saat menangani tugas yang terlihat oleh pengguna, seperti:

Dalam banyak kasus, 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 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, membuat kueri ke 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 untuk 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 untuk menampilkan notifikasi yang terlihat oleh pengguna 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 memakai resource dalam urutan cepat, sehingga mengganggu pengalaman pengguna. Untuk memitigasi 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 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 sehingga memberi tahu 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. Namun, karena dikirim hanya ke aplikasi yang telah diganti paketnya, siaran tersebut akan dikirim ke penerima yang terdaftar di manifes.
  • Aplikasi tetap bisa mendaftar untuk mendapatkan siaran eksplisit dalam manifesnya.
  • Aplikasi dapat menggunakan Context.registerReceiver() pada runtime guna mendaftarkan penerima untuk 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 di perangkat.

Dalam banyak kasus, aplikasi yang sebelumnya telah mendaftar untuk siaran implisit bisa mendapatkan fungsi serupa 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 mendaftarkan penerima untuk ACTION_POWER_CONNECTED dalam manifesnya; saat aplikasi menerima siaran tersebut, aplikasi akan memeriksa apakah pembersihan diperlukan. 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 agar 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(), bukan startService().
  • 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(), bukan startService().
  • Temukan cara untuk menduplikasi fungsi layanan dengan tugas terjadwal. Jika layanan tidak melakukan sesuatu yang langsung terlihat oleh pengguna, Anda biasanya dapat menggunakan tugas terjadwal.
  • Gunakan FCM untuk mengaktifkan aplikasi Anda secara selektif saat terjadi peristiwa jaringan, bukan melakukan polling di latar belakang.
  • Tangguhkan pekerjaan latar belakang hingga aplikasi berada di latar depan dengan sendirinya.

Tinjau penerima siaran yang didefinisikan 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.