← Назад к вопросам

Как передавать данные между Activity?

1.0 Junior🔥 251 комментариев
#Жизненный цикл и навигация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Передача данных между Activity в Android

Передача данных между Activity является фундаментальной задачей в разработке Android приложений. Существует несколько основных подходов, каждый из которых имеет свои преимущества и области применения.

Использование Intent с явными параметрами

Наиболее распространенный и базовый способ — передача данных через Intent при запуске новой Activity.

Передача простых данных (параметры Intent)

Для передачи простых данных (строки, числа, флаги) используются методы putExtra() объекта Intent:

// В исходной Activity
val intent = Intent(this, DestinationActivity::class.java)
intent.putExtra("KEY_USER_NAME", "John Doe")
intent.putExtra("KEY_USER_AGE", 25)
intent.putExtra("KEY_IS_PREMIUM", true)
startActivity(intent)

// В целевой Activity
val userName = intent.getStringExtra("KEY_USER_NAME")
val userAge = intent.getIntExtra("KEY_USER_AGE", 0) // 0 - default value
val isPremium = intent.getBooleanExtra("KEY_IS_PREMIUM", false)

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

Для передачи сложных объектов необходимо реализовать интерфейс Parcelable или Serializable:

// Kotlin: использование Parcelable (более эффективно для Android)
data class User(
    val name: String,
    val age: Int,
    val email: String
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString()!!,
        parcel.readInt(),
        parcel.readString()!!
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(name)
        parcel.writeInt(age)
        parcel.writeString(email)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<User> {
        override fun createFromParcel(parcel: Parcel): User = User(parcel)
        override fun newArray(size: Int): Array<User?> = arrayOfNulls(size)
    }
}

// Передача объекта
val user = User("John", 30, "john@example.com")
val intent = Intent(this, ProfileActivity::class.java)
intent.putExtra("KEY_USER", user)
startActivity(intent)

Использование результата Activity (startActivityForResult)

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

Традиционный подход (менее используемый сейчас)

// Старт Activity с ожиданием результата
val intent = Intent(this, SelectionActivity::class.java)
startActivityForResult(intent, REQUEST_CODE_SELECTION)

// Обработка результата в onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CODE_SELECTION && resultCode == RESULT_OK) {
        val selectedItem = data?.getStringExtra("KEY_SELECTED_ITEM")
        // Использование полученных данных
    }
}

// В целевой Activity установка результата
val resultIntent = Intent()
resultIntent.putExtra("KEY_SELECTED_ITEM", "Выбранный элемент")
setResult(RESULT_OK, resultIntent)
finish()

Современный подход: Activity Result API

В AndroidX появился более удобный Activity Result API, который рекомендуется использовать:

// Регистрация контракта для получения результата
val getResult = registerForActivityResult(
    StartActivityForResult(),
    ActivityResultCallback { result ->
        if (result.resultCode == RESULT_OK) {
            val data = result.data?.getStringExtra("KEY_SELECTED_ITEM")
            // Обработка данных
        }
    }
)

// Запуск Activity через контракт
val intent = Intent(this, SelectionActivity::class.java)
getResult.launch(intent)

Передача данных через SharedViewModel

В архитектуре с Jetpack компонентами, особенно при использовании Navigation Component, эффективным способом передачи данных между Activity (и Fragment) является SharedViewModel.

  • Преимущества: централизованное управление состоянием, независимость от жизненного цикла отдельных Activity
  • Применение: когда несколько Activity или Fragment должны работать с общими данными
// Создание ViewModel, доступного для нескольких Activity
class SharedDataViewModel : ViewModel() {
    val selectedItem: MutableLiveData<String> = MutableLiveData()
    
    fun selectItem(item: String) {
        selectedItem.value = item
    }
}

// В первой Activity
val viewModel: SharedDataViewModel by viewModels()
viewModel.selectItem("Новый элемент")

// Во второй Activity (получение тех же данных)
val viewModel: SharedDataViewModel by viewModels()
viewModel.selectedItem.observe(this) { item ->
    // Обновление UI при изменении данных
}

Другие подходы передачи данных

  • Глобальное состояние приложения:

    • Использование Singleton классов
    • Application класс с публичными свойствами
    • Предостережение: может приводить к проблемам с памятью и сложности тестирования
  • Постоянное хранилище:

    • SharedPreferences для простых данных
    • Local Database (Room, SQLite) для сложных структур
    • Files или Cache для больших данных
    • Используется, когда данные должны сохраняться между сессиями приложения
  • Архитектурные компоненты передачи:

    • Repository паттерн для централизованного доступа к данным
    • Использование EventBus или RxJava для событийной коммуникации
    • Kotlin Flow или LiveData для реактивных потоков данных

Критерии выбора метода передачи данных

  1. Объем и сложность данных:

    • Простые данные → Intent extras
    • Комплексные объекты → Parcelable/Serializable
    • Большие объемы данных → Постоянное хранилище
  2. Направление передачи:

    • Однонаправленная → Intent
    • Двунаправленная (ожидание результата) → Activity Result API
  3. Количество потребителей данных:

    • Один потребитель → Intent
    • Множество потребителей → SharedViewModel или глобальное состояние
  4. Время жизни данных:

    • Только во время сессии → Intent или ViewModel
    • Между сессиями приложения → Persistent Storage

Best Practices и рекомендации

  • Минимизация передачи больших данных через Intent (ограничения по памяти)
  • Использование типизированных ключей (константы или sealed классы) вместо строковых литералов
  • Сериализация/десериализация сложных объектов должна быть эффективной
  • При использовании ViewModel учитывать жизненный цикл компонентов
  • Для результатов Activity предпочтительно использовать современный Activity Result API
  • Избегать глобальных статических переменных для передачи данных (проблемы с памятью и тестированием)

Выбор метода передачи данных зависит от конкретной задачи, архитектуры приложения и требований к производительности. В современных Android приложениях чаще всего комбинируются несколько подходов: Intent для базовой коммуникации, ViewModel для управления состоянием и Persistent Storage для долговременного хранения.