Что такое BroadcastReceiver и какие типы существуют?android-57

BroadcastReceiver — это компонент Android, который позволяет приложению реагировать на системные или пользовательские широковещательные сообщения (broadcasts). Эти сообщения могут быть как системными событиями (например, изменение уровня заряда батареи, подключение к Wi-Fi), так и кастомными, отправленными другими приложениями или самим приложением.

Основные характеристики BroadcastReceiver

  1. Легковесный: Не предназначен для долгих операций (максимум 10 секунд в onReceive()).
  2. Асинхронный: Работает в основном потоке, но не блокирует UI.
  3. Жизненный цикл: Создается при получении сообщения и уничтожается после выполнения onReceive().

Типы BroadcastReceiver

1. Статические

Регистрируются в AndroidManifest.xml и работают даже когда приложение не запущено.
Пример объявления:

<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Особенности:

  • Получают broadcast до запуска приложения (например, BOOT_COMPLETED).
  • Начиная с Android 8.0 (API 26), нельзя регистрировать неявные broadcast (кроме исключений, например, ACTION_BOOT_COMPLETED).

2. Динамические

Регистрируются программно через Context (например, Activity или Service) и работают только пока активен контекст.
Пример регистрации:

val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "Динамический Broadcast получен!", Toast.LENGTH_SHORT).show()
    }
}
val filter = IntentFilter().apply { addAction("com.example.CUSTOM_ACTION") }
registerReceiver(receiver, filter)

Особенности:

  • Гибкость: можно регистрировать/отменять в runtime.
  • Работают только при активном контексте (например, пока Activity не уничтожена).
  • Получают как явные, так и неявные broadcast (если IntentFilter разрешен).

3. Ordered Broadcasts

Особый тип broadcast, который передается получателям последовательно (по приоритету).
Пример отправки:

sendOrderedBroadcast(
    Intent("com.example.ORDERED_ACTION"),
    null, // permission
    receiver, // final receiver
    null, // scheduler
    RESULT_OK,
    null,
    null
)

Особенности:

  • Получатели обрабатываются по очереди (можно прервать цепочку с помощью abortBroadcast()).
  • Приоритет задается в android:priority (для статических) или IntentFilter.setPriority() (для динамических).

4. Sticky Broadcasts

Сообщения, которые "застревают" в системе и передаются новым подписчикам.
Важно: Начиная с Android 5.0 (API 21), помечены как deprecated. Вместо них рекомендуется использовать LocalBroadcastManager или другие механизмы.


Резюмируем

  • Статические — для глобальных событий (например, загрузка системы), регистрируются в манифесте.
  • Динамические — для временных подписок, регистрируются в коде.
  • Ordered — для последовательной обработки с приоритетами.
  • Sticky — устарели, не используйте в новых проектах.

Пример кастомного broadcast:

// Отправка
sendBroadcast(Intent("com.example.MY_ACTION").apply { putExtra("key", "value") })

// Получение (динамическое)
val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val data = intent.getStringExtra("key")
        Log.d("Receiver", "Получено: $data")
    }
}