Как работают Intent и как передавать данные между Activity

Intent — объект в Android, который описывает намерение выполнить действие: запустить Activity, Service или BroadcastReceiver и/или передать данные между ними через extras. Ниже — компактный практический гайд с примерами Java и Kotlin для отправки, приёма и возврата данных.

Оглавление {{TOC_AUTOMATIC}}

Что такое Intent и какие бывают типы

Intent содержит action, data (URI), extras (Bundle) и флаги. Два основных типа:

  • Явный (Explicit) — указываете конкретный класс: используется для переходов внутри вашего приложения.
  • Неявный (Implicit) — описываете действие (например, ACTION_VIEW), а система выбирает подходящий компонент.

Для внутренних переходов всегда предпочитайте явные Intent — они надёжнее и быстрее.

Как передавать простые данные (String, int, boolean)

Данные кладутся в extras с помощью методов putExtra и извлекаются через getStringExtra, getIntExtra и т.д.

Пример Java (MainActivity -> SecondActivity):

// MainActivity
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("user_name", "Иван");
intent.putExtra("user_age", 25);
startActivity(intent);
// SecondActivity - в onCreate
Intent intent = getIntent();
String name = intent.getStringExtra("user_name");
int age = intent.getIntExtra("user_age", 0);

Kotlin эквивалент:

val intent = Intent(this, SecondActivity::class.java).apply {
    putExtra("user_name", "Иван")
    putExtra("user_age", 25)
}
startActivity(intent)

// в SecondActivity
val name = intent.getStringExtra("user_name")
val age = intent.getIntExtra("user_age", 0)

Возврат результата: Activity Result API (современный способ)

startActivityForResult устарел. Используйте Activity Result API:

Kotlin пример:

// Регистрация
private val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val data = result.data
        val message = data?.getStringExtra("result_message")
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
}

// Запуск
val intent = Intent(this, SecondActivity::class.java)
launcher.launch(intent)

В SecondActivity:

val resultIntent = Intent().apply {
    putExtra("result_message", "Данные сохранены!")
}
setResult(Activity.RESULT_OK, resultIntent)
finish()

Не используйте startActivityForResult в новых проектах — переходите на Activity Result API.

Передача сложных объектов: Parcelable vs Serializable

Parcelable быстрее и рекомендуется для Android. Пример сокращённого User (Java):

public class User implements Parcelable {
    private String name;
    private int age;
    // writeToParcel / CREATOR / конструктор из Parcel
}

Передача:

intent.putExtra("user", user); // user implements Parcelable
User user = getIntent().getParcelableExtra("user");

Если объект небольшой и вам проще — можно использовать Serializable, но учтите накладные расходы.

Для проектов с Navigation Component используйте Safe Args — генерирует типобезопасные аргументы для переходов.

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

  • Не проверять наличие extra: используйте intent.hasExtra("key") или null‑проверки.
  • Передача больших данных (Bitmap) через Intent — приведёт к ошибкам. Вместо этого передавайте URI/ссылку или сохраните в кэш.
  • Передача чувствительных данных (пароли, токены) — небезопасно, они могут попасть в логи ADB.
  • Неправильная реализация Parcelable — результат null и краши при чтении.

FAQ

  • Как проверить, есть ли ключ в Intent?

    • if (intent != null && intent.hasExtra("key")) { ... }
  • Можно ли передать List объектов?

    • Да: putParcelableArrayListExtra или putStringArrayListExtra для простых списков.
  • Что лучше для межприложенной передачи — Intent или ContentProvider?

    • Для передачи собственных данных внутри приложения Intent удобен; для безопасного обмена большими объёмами данных между приложениями — ContentProvider.

Заключение: начните с простых extras и явных Intent для навигации внутри приложения; используйте Parcelable для объектов и Activity Result API для возврата данных. Если нужно — пришлю полные Kotlin‑версии примеров или пример с Navigation Component и Safe Args.