Как работать с Intent, Action и extras в Android

Intent — объект для запуска компонентов и доставки сообщений; action описывает цель Intent; extras (Bundle) — место для передачи данных. Используйте явные Intent для внутренних переходов, неявные — для системных действий; для объектов предпочитайте Parcelable.

Что такое Intent и роль Action

Intent — это контейнер: action (строка), data (Uri), category и extras (Bundle).

  • Явный (explicit) Intent: указывает класс компонента — применяется внутри приложения.
  • Неявный (implicit) Intent: указывает действие или MIME-тип; систему выбирает подходящий компонент по .
    Action — строковый идентификатор цели (например, ACTION_VIEW, ACTION_SEND) или кастомный "com.example.MY_ACTION". В неявных Intent action часто комбинируют с data и category для точного сопоставления.

Как передавать данные через extras (практика)

Extras — это Bundle; данные кладут парами ключ → значение. Поддерживаемые типы: примитивы, String, Parcelable, Serializable, массивы и списки.

Примеры записи и чтения в Kotlin:

// Отправка (Activity A)
val intent = Intent(this, SecondActivity::class.java).apply {
    putExtra("userId", 123)
    putExtra("username", "ivan")
    putExtra("payload", myParcelable) // Parcelable
}
startActivity(intent)

// Приём (Activity B)
val userId = intent.getIntExtra("userId", -1)
val username = intent.getStringExtra("username") ?: ""
val payload = intent.getParcelableExtra<MyParcelable>("payload")

Рекомендации:

  • Для объектов реализуйте Parcelable — быстрее и предпочтительнее Serializable.
  • Минимизируйте размер extras: большие объекты лучше передавать через ViewModel, Singletons, или через URI/файл.
  • Всегда проверяйте null и дефолтные значения.

Для обратной передачи данных используйте Activity Result API (заменяет устаревший startActivityForResult). Это надежнее и проще в управлении жизненным циклом.

Не кладите в extras чувствительную информацию (пароли, токены). Extras могут быть видны в логах или ADB.

Запуск компонентов: Activity, Service, Broadcast

Activity:

  • startActivity(intent) — простой запуск.
  • Указывайте флаги при необходимости: FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP.
  • Для результата — Activity Result API.

Service:

  • startService(intent) или startForegroundService(intent) для foreground-сервисов (API 26+).
  • Остановка: stopService(intent) или stopSelf() внутри сервиса.

Broadcast:

  • sendBroadcast(intent) — публичный broadcast.
  • Для локальных событий используйте LocalBroadcastManager или другие локальные механизмы (это безопаснее).

Пример implicit Intent для отправки текста:

val send = Intent(Intent.ACTION_SEND).apply {
    type = "text/plain"
    putExtra(Intent.EXTRA_TEXT, "Поделиться этим")
}
startActivity(Intent.createChooser(send, "Выбрать приложение"))

Частые ошибки

  • Пытаются передать большие объекты через extras — приводит к TransactionTooLargeException. Решение: использовать другие механизмы (ViewModel, файл, DB).
  • Неправильные ключи — код ломается silently. Используйте константы для ключей.
  • Не обрабатывают null и не учитывают дефолтные значения при чтении.
  • Ожидают результат от startActivity вместо использования Activity Result API.

FAQ

  • Как передать объект? — Сделайте его Parcelable и используйте putExtra/getParcelableExtra.
  • Можно ли передать Bitmap через extras? — Технически можно, но не рекомендуется (весит много). Лучше сохранять во временный файл и передавать Uri.
  • Как отловить конкретный implicit Intent? — Опишите соответствующий в манифесте или регистрируйте BroadcastReceiver программно.

Если нужно, могу привести пример полного кода для Activity A ↔ Activity B с Activity Result API и Parcelable.