Посылки и пакеты

Объекты Parcelable и Bundle предназначены для использования на границах процессов, например, в транзакциях IPC/Binder, между действиями с намерениями, а также для хранения временного состояния при изменении конфигурации. На этой странице представлены рекомендации и лучшие практики использования объектов Parcelable и Bundle .

Примечание: Parcel не является универсальным механизмом сериализации, и вам никогда не следует хранить данные Parcel на диске или передавать их по сети.

Передача данных между действиями

Когда приложение создает объект Intent для использования в startActivity() при запуске новой Activity, оно может передавать параметры с помощью метода putExtra() .

Приведённый ниже фрагмент кода демонстрирует пример выполнения этой операции.

val intent = Intent(this, MyActivity::class.java).apply {
    putExtra("media_id", "a1b2c3")
    // ...
}
startActivity(intent)

Операционная система разделяет базовый Bundle намерения (Bundle). Затем ОС создает новое действие (Activity), извлекает данные из пакета и передает намерение новому действию.

Мы рекомендуем использовать класс Bundle для установки примитивов, известных операционной системе, в объектах Intent . Класс Bundle оптимизирован для сериализации и десериализации с использованием пакетов (parcels).

В некоторых случаях может потребоваться передача сложных объектов между активностями или сохранение их в состоянии пользовательского интерфейса. В таких случаях пользовательский класс должен реализовывать интерфейс Parcelable. Для современных приложений Kotlin и Jetpack Compose рекомендуется использовать аннотацию @Parcelize . Она автоматически генерирует логику сериализации, необходимую для безопасной обработки ваших данных при использовании Bundles. Это тот же подход, который используется для обработки ваших данных при использовании rememberSaveable . Для получения дополнительной информации об использовании @Parcelize см. генератор реализаций Parcelable .

При отправке данных через Intent следует соблюдать осторожность и ограничивать размер данных несколькими килобайтами. Отправка слишком большого объема данных может привести к возникновению исключения TransactionTooLargeException .

Передача данных между процессами

Передача данных между процессами аналогична передаче данных между активностями. Однако при передаче данных между процессами мы рекомендуем не использовать пользовательские Parcelable-объекты. Если вы отправляете пользовательский Parcelable объект из одного приложения в другое, необходимо убедиться, что в обоих приложениях (отправляющем и принимающем) присутствует одна и та же версия пользовательского класса. Обычно это может быть общая библиотека, используемая в обоих приложениях. Если ваше приложение попытается отправить пользовательский Parcelable-объект в систему, может возникнуть ошибка, поскольку система не сможет десериализовать класс, о котором она ничего не знает.

Например, приложение может установить будильник, используя класс AlarmManager , и использовать пользовательский объект Parcelable в интент-событии будильника. Когда будильник срабатывает, система изменяет Bundle дополнительных данных интента, добавляя счетчик повторов. Это изменение может привести к удалению пользовательского объекта Parcelable из дополнительных данных. Это, в свою очередь, может привести к сбою приложения при получении измененного интента будильника, поскольку приложение ожидает получить дополнительные данные, которых больше нет.

Буфер транзакций Binder имеет ограниченный фиксированный размер, в настоящее время 1 МБ, который используется всеми транзакциями, выполняемыми в рамках процесса. Поскольку это ограничение установлено на уровне процесса, а не на уровне отдельного действия, эти транзакции включают все транзакции Binder в приложении, такие как startActivity , rememberSaveable (который использует onSaveInstanceState внутри) и любое взаимодействие с системой. При превышении лимита размера генерируется исключение TransactionTooLargeException .

В случае сохранения состояния с помощью rememberSaveable объем данных следует ограничивать, поскольку системный процесс должен хранить предоставленные данные до тех пор, пока пользователь сможет вернуться к этому действию (даже если процесс этого действия будет завершен). Мы рекомендуем сохранять данные в объеме менее 50 КБ.

Примечание: В Android 7.0 (уровень API 24) и выше система генерирует исключение TransactionTooLargeException в качестве исключения времени выполнения. В более ранних версиях Android система отображает только предупреждение в logcat.