Pembatasan sistem pada pekerjaan latar belakang

Proses latar belakang dapat menggunakan banyak memori dan daya baterai. Sebagai contoh, siaran implisit dapat memulai banyak proses latar belakang yang telah mendengarkannya, bahkan jika proses itu mungkin tidak melakukan banyak pekerjaan. Fungsi ini dapat memiliki dampak besar pada kinerja perangkat dan pengalaman pengguna.

Untuk menghindari pembatasan sistem, pastikan Anda menggunakan API yang tepat untuk latar belakang. Tujuan Dokumentasi Ringkasan tugas latar belakang membantu Anda memilih API yang tepat untuk kebutuhan Anda.

Larangan yang diinisialisasi pengguna

Jika aplikasi menunjukkan beberapa perilaku buruk yang dijelaskan di Android vitals, sistem akan meminta pengguna untuk membatasi akses aplikasi itu ke sumber daya sistem.

Jika sistem melihat bahwa aplikasi menggunakan sumber daya berlebihan, sistem akan memberi tahu pengguna, dan memberi pengguna opsi untuk membatasi tindakan aplikasi. Perilaku yang dapat memicu pemberitahuan ini meliputi:

  1. Penguncian layar saat aktif yang berlebihan: 1 penguncian layar saat aktif parsial ditahan selama satu jam saat layar nonaktif
  2. Layanan latar belakang yang berlebihan: Jika aplikasi menargetkan level API yang lebih rendah dari 26 dan memiliki layanan latar belakang yang berlebihan

Pembatasan pasti yang diberlakukan ditentukan oleh produsen perangkat. Sebagai misalnya, pada build AOSP, aplikasi yang dibatasi tidak dapat menjalankan tugas, memicu alarm, atau menggunakan jaringan, kecuali saat aplikasi berada di latar depan.

Pembatasan untuk menerima siaran aktivitas jaringan

Aplikasi tidak menerima siaran CONNECTIVITY_ACTION jika mendaftar ke menerimanya dalam manifes mereka, dan proses yang bergantung pada siaran ini tidak dapat dijalankan. Hal ini dapat menimbulkan masalah bagi aplikasi yang ingin memproses jaringan mengubah atau melakukan aktivitas jaringan massal saat perangkat tersambung ke jaringan tidak berbayar. Beberapa solusi untuk mengatasi pembatasan ini ada di kerangka kerja Android, tetapi memilih yang tepat tergantung pada apa yang dicapai oleh aplikasi Anda.

Menjadwalkan pekerjaan pada koneksi tidak berbayar

Saat membuat WorkRequest, tambahkan NetworkType.UNMETERED Constraint.

fun scheduleWork(context: Context) {
    val workManager = WorkManager.getInstance(context)
    val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
       .setConstraints(
           Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .build()
           )
       .build()

    workManager.enqueue(workRequest)
}

Saat kondisi untuk pekerjaan terpenuhi, aplikasi Anda akan menerima callback untuk dijalankan metode doWork() di class Worker yang ditentukan.

Memantau konektivitas jaringan selagi aplikasi berjalan

Aplikasi yang sedang berjalan masih dapat memproses CONNECTIVITY_CHANGE dengan terdaftar BroadcastReceiver. Namun, ConnectivityManager API menyediakan metode yang lebih tangguh untuk meminta callback hanya ketika jaringan kondisi tertentu terpenuhi.

Objek NetworkRequest menentukan parameter callback jaringan di persyaratan NetworkCapabilities. Anda membuat objek NetworkRequest dengan class NetworkRequest.Builder. registerNetworkCallback lalu teruskan objek NetworkRequest ke sistem. Ketika jaringan terpenuhi, aplikasi akan menerima callback untuk mengeksekusi Metode onAvailable() yang ditentukan dalam Class ConnectivityManager.NetworkCallback.

Aplikasi akan terus menerima callback hingga aplikasi keluar atau memanggil unregisterNetworkCallback().

Pembatasan penerimaan gambar dan siaran video

Aplikasi tidak dapat mengirim atau menerima ACTION_NEW_PICTURE, atau ACTION_NEW_VIDEO. Pembatasan ini membantu mengurangi dampak performa dan pengalaman pengguna saat beberapa aplikasi harus aktif secara berurutan untuk memproses gambar atau video baru.

Menentukan otoritas konten yang memicu pekerjaan

WorkerParameters memungkinkan aplikasi Anda menerima informasi yang berguna tentang apa yang otoritas konten dan URI memicu pekerjaan:

List<Uri> getTriggeredContentUris()

Menampilkan daftar URI yang memicu pekerjaan. Kolom ini kosong jika baik tidak ada URI yang memicu pekerjaan (misalnya, pekerjaan dipicu karena batas waktu atau alasan lain), atau jumlah URI yang berubah lebih besar dari 50.

List<String> getTriggeredContentAuthorities()

Menampilkan daftar string otoritas konten yang telah memicu pekerjaan. Jika daftar yang ditampilkan tidak kosong, gunakan getTriggeredContentUris() untuk mengambil detail URI mana yang telah berubah.

Kode contoh berikut menggantikan metode CoroutineWorker.doWork() serta mencatat otoritas konten dan URI yang telah memicu tugas:

class MyWorker(
    appContext: Context,
    params: WorkerParameters
): CoroutineWorker(appContext, params)
    override suspend fun doWork(): Result {
        StringBuilder().apply {
            append("Media content has changed:\n")
            params.triggeredContentAuthorities
                .takeIf { it.isNotEmpty() }
                ?.let { authorities ->
                    append("Authorities: ${authorities.joinToString(", ")}\n")
                    append(params.triggeredContentUris.joinToString("\n"))
                } ?: append("(No content)")
            Log.i(TAG, toString())
        }
        return Result.success()
    }
}

Menguji aplikasi dengan pembatasan sistem

Mengoptimalkan aplikasi Anda agar berjalan di perangkat bermemori rendah atau dalam kondisi memori rendah, dapat meningkatkan kinerja dan pengalaman pengguna. Menghapus dependensi di latar belakang dan penerima siaran implisit yang terdaftar di manifes bisa membantu aplikasi berjalan lebih baik pada perangkat tersebut. Sebaiknya optimalkan aplikasi Anda agar dapat berjalan tanpa menggunakan proses latar belakang ini sepenuhnya.

Beberapa perintah Android Debug Bridge (ADB) tambahan dapat membantu Anda menguji aplikasi perilaku ini dengan proses latar belakang yang dinonaktifkan:

  • Untuk menyimulasikan kondisi saat siaran implisit dan layanan latar belakang tidak tersedia, masukkan perintah berikut:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore

  • Untuk mengaktifkan kembali siaran implisit dan layanan latar belakang, masukkan berikut:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow

Mengoptimalkan aplikasi Anda lebih jauh

Cara baik lainnya untuk mengoptimalkan tugas latar belakang perilaku, melihat Mengoptimalkan penggunaan baterai untuk API penjadwalan tugas dokumentasi tambahan.