Как работать с 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.