Ответ
Объявление BroadcastReceiver в run-time (через registerReceiver()) рекомендуется, когда нужно реагировать на динамические события только во время работы приложения. Это экономит ресурсы, так как ресивер не активен в фоне, и предотвращает утечки памяти.
Пример:
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// Обработка события
}
}
// Регистрация в onCreate/onStart
val filter = IntentFilter("SOME_ACTION")
registerReceiver(receiver, filter)
// Обязательно отписываться в onDestroy/onStop
unregisterReceiver(receiver)
Плюсы:
- Контроль жизненного цикла (избегаем утечек)
- Работает только когда нужно (оптимизация батареи)
- Гибкость (можно регистрировать/отменять по условиям)
Manifest-объявление (<receiver>) уместно для системных событий (BOOT_COMPLETED), но требует явного экспорта и проверок безопасности.
Ответ 18+ 🔞
А, ну это же классика, ёпта! Смотри, чтобы твоё приложение не превратилось в пиздопроебибну, которая батарею сосёт как не в себя, нужно правильно работать с широковещательными сообщениями.
Вот смотри, если тебе нужно ловить какой-то кастомный ивент, который ты сам же и кидаешь, или слушать что-то ТОЛЬКО пока юзер в приложении — регистрируй ресивер прямо в коде, в рантайме. Это чтобы он не висел в фоне, как хуй с горы, когда уже никому не нужен.
Вот, смотри пример, тут всё просто:
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// Тут делаешь свои дела, когда событие прилетело
}
}
// Цепляешь этого слушателя, когда активити живое (например, в onCreate)
val filter = IntentFilter("SOME_ACTION")
registerReceiver(receiver, filter)
// И ОБЯЗАТЕЛЬНО, блядь, отписываешься, когда активити помирает (в onDestroy)!
unregisterReceiver(receiver)
В чём прикол, спросишь? А прикол в том, что доверия ебать ноль к разработчикам, которые забывают отписаться. Если забудешь — будет у течка памяти, приложение начнёт бздеть и глючить, а система потом прибьёт твой процесс, и ты будешь чесать репу: "э, сабака сука, чё опять сломалось?".
Плюсы этого подхода — овердохуища:
- Контроль жизненного цикла. Ресивер живёт ровно столько, сколько нужно. Закрыл приложение — и он накрылся медным тазом, не жрёт ресурсы.
- Батарейку не жрёт. Он не слушает эфир, пока твоё приложение свёрнуто или убито. Это же не какая-то мартышлюшка в фоне.
- Гибкость. Можешь подписаться на событие в одном месте, а отписаться в другом, по какому-то условию. Полная власть!
А вот объявление в манифесте (<receiver>) — это уже для серьёзных системных вещей, типа "ой, устройство загрузилось" (BOOT_COMPLETED). Но тут, чувак, будь осторожен! Это как ходить по охуенно тонкому льду. Система может разбудить твоё приложение в любой момент, даже если оно закрыто. И если ты там накосячил с безопасностью (не выставил android:exported="false" где надо), то к тебе могут гомосеки налететь — другие приложения начнут слать тебе свои интенты без спроса. В общем, подозрение ебать чувствую к этому способу, используй его только когда без него реально никак.