В любом приложении, где больше одного экрана, возникает задача — передать информацию от одной Activity к другой. Это может быть текст, который ввёл пользователь, выбранный пункт списка, настройки или даже целый объект. В этом уроке из серии android studio kotlin уроки мы разберём все основные способы передачи данных между Activity, от самых простых до современных и рекомендованных.
Intent и putExtra: классический способ
Intent — это универсальный «курьер» в Android, который не только запускает новые Activity, но и может нести с собой данные. Для упаковки данных используется метод putExtra(), принимающий два аргумента: строковый ключ и само значение. Этот подход поддерживает все примитивные типы (String, Int, Boolean и т.д.), их массивы, а также объекты, реализующие интерфейс Serializable.
Рассмотрим классический пример. У нас есть MainActivity с полем ввода и кнопкой, по нажатию на которую мы передаём введённый текст в SecondActivity и открываем её.
Отправка данных (MainActivity.kt)
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("USER_NAME", binding.editText.text.toString())
intent.putExtra("USER_AGE", 25)
startActivity(intent)
Получение данных (SecondActivity.kt)
val userName = intent.getStringExtra("USER_NAME") ?: "Гость"
val userAge = intent.getIntExtra("USER_AGE", 0)
binding.textView.text = "Привет, $userName! Тебе $userAge лет."
Важно: для каждого типа данных существует свой метод получения: getStringExtra(), getIntExtra(), getBooleanExtra() и так далее. Второй параметр у числовых методов — это значение по умолчанию, которое вернётся, если ключ не найден.
Bundle: контейнер для сложных данных
Если данных много, удобно собрать их в объект Bundle. Bundle — это хранилище пар «ключ-значение», похожее на Intent, но позволяющее группировать данные и передавать их единым блоком. С Bundle код становится чище, особенно когда нужно передать большой набор параметров.
// Отправка
val bundle = Bundle().apply {
putString("NAME", "Анна")
putInt("SCORE", 95)
putBoolean("IS_PREMIUM", true)
}
val intent = Intent(this, SecondActivity::class.java).apply { putExtras(bundle) }
startActivity(intent)
// Получение
val bundle = intent.extras
val name = bundle?.getString("NAME") ?: "Гость"
val score = bundle?.getInt("SCORE") ?: 0
Такой подход особенно полезен, когда данные передаются через несколько экранов или когда они приходят из другого источника (например, push-уведомления).
Передача объектов: Parcelable
Передавать отдельные строки и числа — это хорошо, но в реальных приложениях гораздо чаще нужно передать целый объект: данные пользователя, товар, заказ. Для этого в Android есть два основных механизма: Serializable (медленный, но простой) и Parcelable (быстрый, но требует больше кода). Google рекомендует использовать именно Parcelable, а Kotlin делает это невероятно простым благодаря аннотации @Parcelize.
Для использования @Parcelize добавьте в build.gradle.kts (модуль app) плагин:
plugins {
id("kotlin-parcelize")
}
Теперь создадим data-класс, реализующий Parcelable:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class User(
val id: Int,
val name: String,
val email: String
) : Parcelable
Передача объекта:
// Отправка
val user = User(1, "Алексей", "alex@example.com")
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("USER_DATA", user)
startActivity(intent)
// Получение
val user = intent.getParcelableExtra<User>("USER_DATA")
user?.let {
binding.textView.text = "Пользователь: ${it.name}, Email: ${it.email}"
}
Использование Parcelable гораздо эффективнее Serializable, особенно при частых передачах или работе с большими объектами.
Возврат данных: Activity Result API
Иногда нужно не просто передать данные в другую Activity, но и получить результат обратно. Раньше для этого использовали методы startActivityForResult() и onActivityResult(), но они давно объявлены устаревшими (deprecated). Современный подход — Activity Result API, который проще, безопаснее и не требует ручного управления кодами запросов.
Вот как это работает. Сначала в первой Activity регистрируем «ланчер» — специальный объект, который будет запускать вторую Activity и обрабатывать результат:
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val returnedData = result.data?.getStringExtra("RESULT_KEY")
binding.textView.text = "Получено: $returnedData"
}
}
Затем запускаем вторую Activity через этот ланчер:
val intent = Intent(this, SecondActivity::class.java)
launcher.launch(intent)
Во второй Activity формируем результат и закрываем экран:
val resultIntent = Intent().apply {
putExtra("RESULT_KEY", "Данные со второго экрана")
}
setResult(Activity.RESULT_OK, resultIntent)
finish()
Преимущества Activity Result API очевидны: код обработки результата находится рядом с кодом запуска, не нужно думать о requestCode, и всё это безопасно работает с жизненным циклом компонентов.
Альтернативные способы и когда их не стоит использовать
Кроме Intent, существуют и другие механизмы обмена данными между Activity, но у каждого есть свои нюансы:
- Глобальные переменные (static, companion object) — крайне ненадёжный способ. Данные теряются при пересоздании Activity (поворот экрана, сворачивание приложения) и могут вызывать утечки памяти. Используйте только для констант.
- SharedPreferences / DataStore — отлично подходят для долговременного хранения настроек, но не для передачи данных между экранами в рамках одного сеанса. Операции записи/чтения медленные и асинхронные.
- База данных (Room) — подходит для сложных структур данных, которые нужны в разных частях приложения. Но для простой передачи строки или числа — это как «стрелять из пушки по воробьям».
- ViewModel — идеальный инструмент для хранения данных, связанных с конкретным экраном, но не для передачи между независимыми Activity (ViewModel привязана к жизненному циклу конкретной Activity). Однако если вы используете Single Activity архитектуру с фрагментами, общий ViewModel — лучший выбор.
- Event Bus (LiveData, Flow) — может использоваться для коммуникации между компонентами, но злоупотребление ими усложняет отладку и понимание потоков данных.
Сводная таблица: какой метод выбрать?
Итоги
Мы разобрали ключевые способы передачи данных между Activity в рамках android studio kotlin уроки. Базовый Intent с putExtra() отлично подходит для простых сценариев, Bundle помогает структурировать множество параметров, Parcelable позволяет передавать сложные объекты, а Activity Result API — современный стандарт для получения обратной связи. Выбирайте метод в зависимости от задачи, и ваше приложение будет работать предсказуемо и надёжно. Практикуйтесь, экспериментируйте, и совсем скоро передача данных станет для вас рутинной и понятной операцией!