Aplikasi Android mengirim dan menerima pesan siaran dari sistem Android dan aplikasi Android lainnya, mirip dengan pola desain publish-subscribe. Sistem dan aplikasi biasanya mengirim siaran saat peristiwa tertentu terjadi. Misalnya, sistem Android mengirim siaran saat berbagai peristiwa sistem terjadi, seperti booting sistem atau pengisian daya perangkat. Aplikasi juga mengirim siaran kustom, misalnya, untuk memberi tahu aplikasi lain tentang sesuatu yang mungkin menarik bagi mereka (misalnya, download data baru).
Aplikasi dapat mendaftar untuk menerima siaran tertentu. Saat siaran dikirim, sistem akan otomatis merutekan siaran ke aplikasi yang telah berlangganan untuk menerima jenis siaran tertentu tersebut.
Secara umum, siaran dapat digunakan sebagai sistem pesan di seluruh aplikasi dan di luar alur pengguna normal. Namun, Anda harus berhati-hati agar tidak menyalahgunakan peluang untuk merespons siaran dan menjalankan tugas di latar belakang yang dapat memperlambat performa sistem.
Tentang siaran sistem
Sistem akan otomatis mengirim siaran saat berbagai peristiwa sistem terjadi, seperti saat sistem beralih ke dan keluar dari Mode Pesawat. Semua aplikasi yang berlangganan menerima siaran ini.
Objek Intent membungkus pesan siaran. String action mengidentifikasi
peristiwa yang terjadi, seperti android.intent.action.AIRPLANE_MODE. Maksud
juga dapat menyertakan informasi tambahan yang digabungkan ke dalam kolom tambahan.
Misalnya, maksud Mode Pesawat menyertakan ekstra boolean yang menunjukkan
apakah Mode Pesawat aktif atau tidak.
Untuk mengetahui informasi selengkapnya tentang cara membaca intent dan mendapatkan string tindakan dari intent, lihat Intent dan Filter Intent.
Tindakan siaran sistem
Untuk melihat daftar lengkap tindakan siaran sistem, lihat file BROADCAST_ACTIONS.TXT
di Android SDK. Setiap tindakan siaran memiliki kolom konstanta yang terkait
dengannya. Misalnya, nilai konstanta
ACTION_AIRPLANE_MODE_CHANGED adalah android.intent.action.AIRPLANE_MODE.
Dokumentasi untuk setiap tindakan siaran tersedia di kolom konstanta terkait.
Perubahan pada siaran sistem
Seiring berkembangnya platform Android, platform ini secara berkala mengubah perilaku siaran sistem. Perhatikan perubahan berikut untuk mendukung semua versi Android.
Android 16
Di Android 16, urutan pengiriman siaran menggunakan atribut android:priority
atau IntentFilter.setPriority() di berbagai proses
tidak akan dijamin. Prioritas siaran hanya dipatuhi
dalam proses aplikasi yang sama, bukan di semua proses.
Selain itu, prioritas siaran secara otomatis dibatasi ke rentang
(SYSTEM_LOW_PRIORITY + 1, SYSTEM_HIGH_PRIORITY - 1).
Hanya komponen sistem yang diizinkan untuk menetapkan SYSTEM_LOW_PRIORITY,
SYSTEM_HIGH_PRIORITY sebagai prioritas siaran.
Android 14
Saat aplikasi berada dalam status di-cache, sistem mengoptimalkan pengiriman siaran
untuk kesehatan sistem. Misalnya, sistem menunda siaran sistem yang kurang penting seperti ACTION_SCREEN_ON saat aplikasi dalam status di-cache.
Setelah aplikasi beralih dari status yang di-cache ke siklus proses aktif,
sistem akan mengirimkan siaran yang ditangguhkan.
Siaran penting yang dideklarasikan dalam manifes akan menghapus aplikasi dari status cache untuk pengiriman sementara.
Android 9
Mulai Android 9 (level API 28), siaran NETWORK_STATE_CHANGED_ACTION
tidak menerima informasi tentang lokasi pengguna atau data identitas pribadi.
Jika aplikasi Anda diinstal di perangkat yang menjalankan Android 9.0 (level API 28) atau yang lebih tinggi, sistem tidak menyertakan SSID, BSSID, informasi koneksi, atau hasil pemindaian dalam siaran Wi-Fi. Untuk mendapatkan informasi ini, panggil
getConnectionInfo().
Android 8.0
Mulai Android 8.0 (level API 26), sistem memberlakukan batasan tambahan pada penerima yang dideklarasikan dalam manifes.
Jika aplikasi Anda menargetkan Android 8.0 atau yang lebih tinggi, Anda tidak dapat menggunakan manifes untuk mendeklarasikan penerima untuk sebagian besar siaran implisit (siaran yang tidak menargetkan aplikasi Anda secara khusus). Anda tetap dapat menggunakan penerima yang terdaftar dalam konteks saat pengguna secara aktif menggunakan aplikasi Anda.
Android 7.0
Android 7.0 (level API 24) dan yang lebih tinggi tidak mengirim siaran sistem berikut:
Selain itu, aplikasi yang menargetkan Android 7.0 dan yang lebih tinggi harus mendaftarkan siaran
CONNECTIVITY_ACTION menggunakan
registerReceiver(BroadcastReceiver, IntentFilter). Mendeklarasikan penerima
dalam manifes tidak berfungsi.
Menerima siaran
Aplikasi dapat menerima siaran dengan dua cara: melalui penerima yang terdaftar dalam konteks dan penerima yang dideklarasikan dalam manifes.
Penerima yang terdaftar dalam konteks
Penerima yang terdaftar dalam konteks menerima siaran selama konteks pendaftarannya valid. Ini biasanya terjadi di antara panggilan ke registerReceiver dan
unregisterReceiver. Konteks pendaftaran juga menjadi tidak valid saat
sistem menghancurkan konteks yang sesuai. Misalnya, jika Anda mendaftar dalam konteks
Activity, Anda akan menerima siaran selama aktivitas
tetap aktif. Jika Anda mendaftar dengan konteks Aplikasi, Anda akan menerima siaran selama aplikasi berjalan.
Untuk mendaftarkan penerima dalam konteks, lakukan langkah-langkah berikut:
Dalam file build tingkat modul aplikasi Anda, sertakan versi 1.9.0 atau yang lebih tinggi dari library AndroidX Core:
Groovy
dependencies { def core_version = "1.19.1" // Java language implementation implementation "androidx.core:core:$core_version" // Kotlin implementation "androidx.core:core-ktx:$core_version" // To use RoleManagerCompat implementation "androidx.core:core-role:1.1.0" // To use the Animator APIs implementation "androidx.core:core-animation:1.0.0" // To test the Animator APIs androidTestImplementation "androidx.core:core-animation-testing:1.0.0" // Optional - To enable APIs that query the performance characteristics of GMS devices. implementation "androidx.core:core-performance:1.0.0" // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google implementation "androidx.core:core-google-shortcuts:1.1.0" // Optional - to support backwards compatibility of RemoteViews implementation "androidx.core:core-remoteviews:1.1.0" // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12 implementation "androidx.core:core-splashscreen:1.2.0" }
Kotlin
dependencies { val core_version = "1.19.1" // Java language implementation implementation("androidx.core:core:$core_version") // Kotlin implementation("androidx.core:core-ktx:$core_version") // To use RoleManagerCompat implementation("androidx.core:core-role:1.1.0") // To use the Animator APIs implementation("androidx.core:core-animation:1.0.0") // To test the Animator APIs androidTestImplementation("androidx.core:core-animation-testing:1.0.0") // Optional - To enable APIs that query the performance characteristics of GMS devices. implementation("androidx.core:core-performance:1.0.0") // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google implementation("androidx.core:core-google-shortcuts:1.1.0") // Optional - to support backwards compatibility of RemoteViews implementation("androidx.core:core-remoteviews:1.1.0") // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12 implementation("androidx.core:core-splashscreen:1.2.0") }
Buat instance
BroadcastReceiver:Kotlin
val myBroadcastReceiver = MyBroadcastReceiver()Java
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();Buat instance
IntentFilter:Kotlin
val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")Java
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");Pilih apakah penerima siaran harus diekspor dan terlihat oleh aplikasi lain di perangkat. Jika penerima ini memproses siaran yang dikirim dari sistem atau dari aplikasi lain—bahkan aplikasi lain yang Anda miliki—gunakan flag
RECEIVER_EXPORTED. Jika penerima ini hanya memproses siaran yang dikirim oleh aplikasi Anda, gunakan tandaRECEIVER_NOT_EXPORTED.Kotlin
val listenToBroadcastsFromOtherApps = false val receiverFlags = if (listenToBroadcastsFromOtherApps) { ContextCompat.RECEIVER_EXPORTED } else { ContextCompat.RECEIVER_NOT_EXPORTED }Java
boolean listenToBroadcastsFromOtherApps = false; int receiverFlags = listenToBroadcastsFromOtherApps ? ContextCompat.RECEIVER_EXPORTED : ContextCompat.RECEIVER_NOT_EXPORTED;Daftarkan penerima dengan memanggil
registerReceiver():Kotlin
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)Java
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);Untuk berhenti menerima siaran, panggil
unregisterReceiver(android.content.BroadcastReceiver). Pastikan untuk membatalkan pendaftaran penerima saat Anda tidak lagi memerlukannya atau konteksnya tidak lagi valid.
Membatalkan pendaftaran penerima siaran
Saat penerima siaran didaftarkan, penerima tersebut menyimpan referensi ke Context yang Anda gunakan untuk mendaftarkannya. Hal ini berpotensi menyebabkan kebocoran jika cakupan terdaftar penerima melebihi cakupan siklus proses Konteks. Misalnya, hal ini dapat terjadi saat Anda mendaftarkan penerima pada cakupan Aktivitas, tetapi Anda lupa membatalkan pendaftarannya saat sistem menghancurkan Aktivitas. Oleh karena itu, selalu batalkan pendaftaran penerima siaran Anda.
Kotlin
class MyActivity : ComponentActivity() {
private val myBroadcastReceiver = MyBroadcastReceiver()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags)
setContent { MyApp() }
}
override fun onDestroy() {
super.onDestroy()
// When you forget to unregister your receiver here, you're causing a leak!
this.unregisterReceiver(myBroadcastReceiver)
}
}
Java
class MyActivity extends ComponentActivity {
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags);
// Set content
}
}
Mendaftarkan penerima dalam cakupan terkecil
Penerima siaran Anda hanya boleh didaftarkan saat Anda benar-benar tertarik dengan hasilnya. Pilih cakupan penerima sekecil mungkin:
LifecycleResumeEffectatau metode siklus prosesonResume/onPauseaktivitas: Penerima siaran hanya menerima update saat aplikasi berada dalam status dilanjutkan.LifecycleStartEffectatau metode siklus prosesonStart/onStopaktivitas: Penerima siaran hanya menerima update saat aplikasi berada dalam status dilanjutkan.DisposableEffect: Penerima siaran hanya menerima update saat fungsi composable berada di hierarki komposisi. Cakupan ini tidak dilampirkan ke cakupan siklus proses aktivitas. Pertimbangkan untuk mendaftarkan penerima di konteks aplikasi. Hal ini karena composable secara teoretis dapat melebihi cakupan siklus proses aktivitas dan menyebabkan kebocoran aktivitas.- Aktivitas
onCreate/onDestroy: Penerima siaran menerima update saat aktivitas berada dalam status dibuat. Pastikan untuk membatalkan pendaftaran dionDestroy(), bukanonSaveInstanceState(Bundle), karena hal ini mungkin tidak dipanggil. - Cakupan kustom: Misalnya, Anda dapat mendaftarkan penerima di cakupan
ViewModelAnda, sehingga penerima tersebut tetap ada setelah pembuatan ulang aktivitas. Pastikan untuk menggunakan konteks aplikasi untuk mendaftarkan penerima, karena penerima dapat bertahan lebih lama dari cakupan siklus proses aktivitas dan menyebabkan kebocoran aktivitas.
Membuat composable stateful dan stateless
Compose memiliki composable stateful dan stateless. Mendaftarkan atau membatalkan pendaftaran penerima siaran di dalam composable akan membuatnya stateful. Composable bukan fungsi deterministik yang merender konten yang sama saat parameter yang sama diteruskan. Status internal dapat berubah berdasarkan panggilan ke penerima siaran yang terdaftar.
Sebagai praktik terbaik di Compose, sebaiknya Anda membagi composable menjadi versi stateful dan stateless. Oleh karena itu, sebaiknya Anda mengangkat pembuatan penerima siaran dari Composable untuk membuatnya stateless:
@Composable
fun MyStatefulScreen() {
val myBroadcastReceiver = remember { MyBroadcastReceiver() }
val context = LocalContext.current
LifecycleStartEffect(true) {
// ...
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, flags)
onStopOrDispose { context.unregisterReceiver(myBroadcastReceiver) }
}
MyStatelessScreen()
}
@Composable
fun MyStatelessScreen() {
// Implement your screen
}
Penerima yang dinyatakan manifes
Jika Anda mendeklarasikan penerima siaran dalam manifes, sistem akan meluncurkan aplikasi Anda saat siaran dikirim. Jika aplikasi belum berjalan, sistem akan meluncurkan aplikasi.
Untuk menyatakan penerima siaran dalam manifes, lakukan langkah-langkah berikut:
Tentukan elemen
<receiver>dalam manifes aplikasi Anda.<!-- If this receiver listens for broadcasts sent from the system or from other apps, even other apps that you own, set android:exported to "true". --> <receiver android:name=".MyBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.example.snippets.ACTION_UPDATE_DATA" /> </intent-filter> </receiver>Filter intent menentukan tindakan siaran yang diikuti oleh penerima Anda.
Subclass
BroadcastReceiverdan terapkanonReceive(Context, Intent). Penerima siaran dalam contoh berikut mencatat dan menampilkan konten siaran:Kotlin
class MyBroadcastReceiver : BroadcastReceiver() { @Inject lateinit var dataRepository: DataRepository override fun onReceive(context: Context, intent: Intent) { if (intent.action == "com.example.snippets.ACTION_UPDATE_DATA") { val data = intent.getStringExtra("com.example.snippets.DATA") ?: "No data" // Do something with the data, for example send it to a data repository: dataRepository.updateData(data) } } }Java
public static class MyBroadcastReceiver extends BroadcastReceiver { @Inject DataRepository dataRepository; @Override public void onReceive(Context context, Intent intent) { if (Objects.equals(intent.getAction(), "com.example.snippets.ACTION_UPDATE_DATA")) { String data = intent.getStringExtra("com.example.snippets.DATA"); // Do something with the data, for example send it to a data repository: if (data != null) { dataRepository.updateData(data); } } } }
Pengelola paket sistem akan mendaftarkan penerima setelah aplikasi terinstal. Penerima kemudian menjadi titik entri terpisah ke dalam aplikasi Anda, yang berarti bahwa sistem dapat memulai aplikasi dan mengirimkan siaran jika aplikasi tidak berjalan.
Sistem membuat objek komponen BroadcastReceiver baru untuk menangani
setiap siaran yang diterimanya. Objek ini hanya valid selama durasi
panggilan ke onReceive(Context, Intent). Setelah kode Anda kembali dari metode ini, sistem menganggap komponen tidak lagi aktif.
Efek pada status proses
Apakah BroadcastReceiver Anda beroperasi atau tidak memengaruhi proses yang ada di dalamnya, yang dapat mengubah kemungkinan penghentian proses oleh sistem. Proses latar depan
mengeksekusi metode onReceive() penerima. Sistem menjalankan proses
kecuali dalam kondisi tekanan memori ekstrem.
Sistem menonaktifkan BroadcastReceiver setelah onReceive().
Signifikansi proses host penerima
bergantung pada komponen aplikasinya. Jika proses tersebut hanya menghosting penerima yang dideklarasikan manifes, sistem dapat menghentikannya setelah onReceive()
untuk membebaskan resource bagi proses lain yang lebih penting. Hal ini umum terjadi pada aplikasi yang belum pernah atau tidak baru-baru ini berinteraksi dengan pengguna.
Oleh karena itu, penerima siaran tidak boleh memulai thread latar belakang yang berjalan lama.
Sistem dapat menghentikan proses kapan saja setelah onReceive() untuk merebut kembali
memori, sehingga menghentikan thread yang dibuat. Agar proses tetap berjalan, jadwalkan
JobService dari penerima menggunakan JobScheduler sehingga
sistem mengetahui bahwa proses masih berjalan. Ringkasan Pekerjaan Latar Belakang
memberikan detail selengkapnya.
Mengirim siaran
Android menyediakan dua cara bagi aplikasi untuk mengirim siaran:
- Metode
sendOrderedBroadcast(Intent, String)mengirim siaran ke satu penerima dalam satu waktu. Karena dijalankan secara bergantian, setiap penerima dapat menyebarkan hasil ke penerima berikutnya. Tindakan ini juga dapat membatalkan siaran sepenuhnya sehingga tidak mencapai penerima lain. Anda dapat mengontrol urutan penerima berjalan dalam proses aplikasi yang sama. Untuk melakukannya, gunakan atributandroid:prioritydari intent-filter yang cocok. Penerima dengan prioritas yang sama dijalankan dalam urutan arbitrer. - Metode
sendBroadcast(Intent)mengirim siaran ke semua penerima dalam urutan yang tidak ditentukan. Ini disebut Siaran Normal. Hal ini lebih efisien, tetapi berarti penerima tidak dapat membaca hasil dari penerima lain, menyebarkan data yang diterima dari siaran, atau membatalkan siaran.
Cuplikan kode berikut menunjukkan cara mengirim siaran dengan membuat
Intent dan memanggil sendBroadcast(Intent).
Kotlin
val intent = Intent("com.example.snippets.ACTION_UPDATE_DATA").apply {
putExtra("com.example.snippets.DATA", newData)
setPackage("com.example.snippets")
}
context.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
intent.putExtra("com.example.snippets.DATA", newData);
intent.setPackage("com.example.snippets");
context.sendBroadcast(intent);
Pesan siaran di-wrap dalam objek Intent. String
action intent harus memberikan sintaksis nama paket Java aplikasi dan mengidentifikasi
peristiwa siaran secara unik. Anda dapat melampirkan informasi tambahan ke
intent dengan putExtra(String, Bundle). Anda juga dapat membatasi siaran ke
sekumpulan aplikasi dalam organisasi yang sama dengan memanggil setPackage(String) pada
intent.
Membatasi siaran dengan izin
Izin memungkinkan Anda membatasi siaran ke kumpulan aplikasi yang memiliki izin tertentu. Anda dapat menerapkan batasan pada pengirim atau penerima siaran.
Mengirim siaran dengan izin
Saat memanggil sendBroadcast(Intent, String) atau
sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
Bundle)
, Anda dapat menentukan parameter izin. Hanya penerima yang telah meminta izin tersebut dengan tag <uses-permission> dalam manifesnya yang dapat menerima siaran. Jika izin berbahaya, Anda harus memberikan izin sebelum
penerima dapat menerima siaran. Misalnya, kode berikut mengirimkan siaran dengan izin:
Kotlin
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)
Java
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
Untuk menerima siaran, aplikasi penerima harus meminta izin sebagai berikut:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Anda dapat menentukan izin sistem yang ada seperti
BLUETOOTH_CONNECT atau menentukan izin kustom dengan elemen
<permission>. Untuk mengetahui informasi tentang izin dan keamanan secara umum, lihat Izin Sistem.
Menerima siaran dengan izin
Jika Anda menentukan parameter izin saat mendaftarkan penerima siaran
(baik dengan
registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) atau di
tag <receiver> dalam manifes), maka hanya penyiar yang telah
meminta izin dengan tag <uses-permission> dalam
manifesnya yang dapat mengirim Intent ke penerima. Jika izin berbahaya,
penyiar juga harus diberi izin.
Misalnya, asumsikan aplikasi penerima Anda memiliki penerima yang dideklarasikan dalam manifes sebagai berikut:
<!-- If this receiver listens for broadcasts sent from the system or from
other apps, even other apps that you own, set android:exported to "true". -->
<receiver
android:name=".MyBroadcastReceiverWithPermission"
android:permission="android.permission.ACCESS_COARSE_LOCATION"
android:exported="true">
<intent-filter>
<action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
</intent-filter>
</receiver>
Atau aplikasi penerima Anda memiliki penerima yang terdaftar dalam konteks sebagai berikut:
Kotlin
ContextCompat.registerReceiver(
context, myBroadcastReceiver, filter,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
null, // scheduler that defines thread, null means run on main thread
receiverFlags
)
Java
ContextCompat.registerReceiver(
context, myBroadcastReceiver, filter,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
null, // scheduler that defines thread, null means run on main thread
receiverFlags
);
Kemudian, agar dapat mengirim siaran ke penerima tersebut, aplikasi pengirim harus meminta izin sebagai berikut:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Menghindari siaran dalam proses yang sama
Siaran dirancang sebagai mekanisme komunikasi antar-proses (IPC) untuk mengirim pesan di berbagai aplikasi atau antara sistem dan aplikasi. Mengirim siaran mandiri, yaitu siaran yang semua penerimanya berjalan dalam proses yang sama dengan yang mengirim siaran, sangat tidak efisien, menciptakan overhead sistem yang tidak perlu, dan sangat tidak disarankan.
Dua skenario umum saat aplikasi mengirim siaran ke dirinya sendiri meliputi:
Berkomunikasi antar-komponen dalam proses yang sama: Misalnya, meneruskan peristiwa atau data antar-aktivitas, fragmen, layanan, atau thread latar belakang. Daripada mengirim siaran, gunakan mekanisme komunikasi dalam proses standar seperti pola pengamat atau streaming reaktif:
- Flow Kotlin (
SharedFlowdanStateFlow): Solusi modern dan idiomatis di Kotlin untuk memancarkan dan mengamati aliran peristiwa atau update status di seluruh coroutine dan komponen di aplikasi Anda. ViewModelbersama: Memfasilitasi berbagi data dan peristiwa antar-komponen UI yang berbeda (seperti fragmen atau composable) dalam aktivitas yang sama.- Callback dan pemroses: Callback antarmuka standar atau referensi fungsi yang diteruskan secara langsung antar-komponen atau terdaftar dengan repositori atau pengontrol pusat.
- Flow Kotlin (
Menangani peristiwa, tugas, atau alarm sistem: Misalnya, menerima tugas terjadwal, alarm, atau callback sistem, lalu mengirim siaran untuk memicu tugas yang sebenarnya. Daripada mengirim siaran, selesaikan pekerjaan langsung dalam tugas tersebut (seperti pekerja
JobServiceatau WorkManager), pengendali alarm, atau komponen callback sistem, atau lakukan delegasi langsung ke class logika bisnis aplikasi Anda.
Pada perangkat yang menjalankan Android 17 QPR2 atau yang lebih tinggi, sistem mengirimkan siaran mandiri secara lebih efisien dengan mengembalikannya ke proses pengiriman, yang mengirimkannya ke penerimanya sendiri di thread utama. Mengirim siaran mandiri tidak meningkatkan kepentingan proses Anda dan tidak mencegah proses yang di-cache dibekukan, jadi jangan mengandalkan siaran mandiri untuk membuat aplikasi Anda tetap berjalan atau melakukan pekerjaan di latar belakang. Meskipun dengan pengoptimalan ini, siaran mandiri kurang efisien dibandingkan mekanisme komunikasi dalam proses, jadi gunakan alternatif tersebut.
Untuk mengetahui informasi selengkapnya tentang mendesain komunikasi antar-komponen aplikasi, lihat Panduan arsitektur aplikasi.
Pertimbangan keamanan
Berikut beberapa pertimbangan keamanan untuk mengirim dan menerima siaran:
Jika banyak aplikasi telah terdaftar untuk menerima siaran yang sama dalam manifesnya, hal ini dapat menyebabkan sistem meluncurkan banyak aplikasi, sehingga berdampak besar pada performa perangkat dan pengalaman pengguna. Untuk menghindarinya, sebaiknya gunakan pendaftaran konteks daripada deklarasi manifes. Terkadang, sistem Android itu sendiri menerapkan penggunaan penerima yang terdaftar dalam konteks. Misalnya, siaran
CONNECTIVITY_ACTIONhanya dikirim ke penerima yang terdaftar dalam konteks.Jangan menyiarkan informasi sensitif menggunakan intent implisit. Aplikasi apa pun dapat membaca informasi jika mendaftar untuk menerima siaran. Ada tiga cara untuk mengontrol siapa saja yang dapat menerima siaran Anda:
- Anda dapat menentukan izin saat mengirimkan siaran.
- Di Android 4.0 (level API 14) dan yang lebih tinggi, Anda dapat menentukan
paket dengan
setPackage(String)saat mengirim siaran. Sistem membatasi siaran ke kumpulan aplikasi yang cocok dengan paket.
Saat Anda mendaftarkan penerima, aplikasi apa pun dapat mengirim siaran yang berpotensi berbahaya ke penerima aplikasi Anda. Ada beberapa cara untuk membatasi siaran yang diterima aplikasi Anda:
- Anda dapat menentukan izin saat mendaftarkan penerima siaran.
- Untuk penerima yang dideklarasikan manifes, Anda dapat menyetel atribut android:exported ke "false" dalam manifes. Penerima tidak menerima siaran dari sumber di luar aplikasi.
Ruang nama untuk tindakan siaran bersifat global. Pastikan nama tindakan dan string lainnya ditulis dalam namespace yang Anda miliki. Jika tidak, Anda mungkin secara tidak sengaja bertentangan dengan aplikasi lain.
Karena metode
onReceive(Context, Intent)penerima berjalan di thread utama, metode tersebut harus dijalankan dan ditampilkan dengan cepat. Jika Anda perlu melakukan pekerjaan yang berjalan lama, berhati-hatilah saat membuat thread atau memulai layanan latar belakang karena sistem dapat menghentikan seluruh proses setelahonReceive()ditampilkan. Untuk mengetahui informasi selengkapnya, lihat Efek pada status proses. Untuk melakukan pekerjaan yang berjalan lama, sebaiknya:- Memanggil
goAsync()dalam metodeonReceive()penerima dan meneruskanBroadcastReceiver.PendingResultke thread latar belakang. Hal ini membuat siaran tetap aktif setelah kembali darionReceive(). Namun, bahkan dengan pendekatan ini, sistem mengharapkan Anda menyelesaikan siaran dengan sangat cepat (di bawah 10 detik). Hal ini memungkinkan Anda memindahkan pekerjaan ke thread lain untuk menghindari gangguan pada thread utama. - Menjadwalkan tugas dengan
JobScheduler. Untuk mengetahui informasi selengkapnya, lihat Penjadwalan Tugas Cerdas.
- Memanggil
Jangan memulai aktivitas dari penerima siaran karena pengalaman pengguna akan terganggu, terutama jika ada lebih dari satu penerima. Sebagai gantinya, pertimbangkan untuk menampilkan notifikasi.