Объекты Parcelable
и Bundle
предназначены для использования за пределами границ процесса, например, с транзакциями IPC/Binder, между действиями с намерениями, а также для хранения переходного состояния при изменениях конфигурации. На этой странице представлены рекомендации и лучшие практики по использованию объектов Parcelable
и Bundle
.
Примечание. Parcel
не является механизмом сериализации общего назначения, и вам никогда не следует хранить какие-либо данные Parcel
на диске или отправлять их по сети.
Отправка данных между действиями
Когда приложение создает объект Intent
для использования в startActivity(android.content.Intent)
при запуске нового действия, приложение может передавать параметры с помощью метода putExtra(java.lang.String, java.lang.String)
.
В следующем фрагменте кода показан пример выполнения этой операции.
Котлин
val intent = Intent(this, MyActivity::class.java).apply { putExtra("media_id", "a1b2c3") // ... } startActivity(intent)
Ява
Intent intent = new Intent(this, MyActivity.class); intent.putExtra("media_id", "a1b2c3"); // ... startActivity(intent);
ОС разделяет базовый Bundle
намерения. Затем ОС создает новое действие, распаковывает данные и передает намерение новому действию.
Мы рекомендуем использовать класс Bundle
для установки примитивов, известных ОС, в объектах Intent
. Класс Bundle
хорошо оптимизирован для маршаллинга и демаршаллинга с использованием посылок.
В некоторых случаях вам может понадобиться механизм для отправки составных или сложных объектов между действиями. В таких случаях пользовательский класс должен реализовать Parcelable и предоставить соответствующий метод writeToParcel(android.os.Parcel, int)
. Он также должен предоставить ненулевое поле под названием CREATOR
, которое реализует интерфейс Parcelable.Creator
, метод createFromParcel()
которого используется для преобразования Parcel
обратно в текущий объект. Дополнительные сведения см. в справочной документации по объекту Parcelable
.
При отправке данных через намерение следует соблюдать осторожность и ограничивать размер данных несколькими КБ. Отправка слишком большого количества данных может привести к тому, что система выдаст исключение TransactionTooLargeException
.
Передача данных между процессами
Отправка данных между процессами аналогична отправке данных между действиями. Однако при отправке между процессами мы рекомендуем не использовать специальные посылки. Если вы отправляете пользовательский объект Parcelable
из одного приложения в другое, вам необходимо быть уверенным, что одна и та же версия пользовательского класса присутствует как в отправляющем, так и в принимающем приложении. Обычно это может быть общая библиотека, используемая в обоих приложениях. Ошибка может возникнуть, если ваше приложение попытается отправить в систему пользовательский пакет, поскольку система не может демаршалировать класс, о котором ей не известно.
Например, приложение может установить сигнал тревоги с помощью класса AlarmManager
и использовать пользовательский Parcelable
для намерения сигнала тревоги. Когда срабатывает будильник, система изменяет Bundle
дополнений намерения, добавляя счетчик повторений. Эта модификация может привести к удалению системой пользовательского Parcelable
из дополнений. Это удаление, в свою очередь, может привести к сбою приложения при получении измененного намерения тревоги, поскольку приложение ожидает получения дополнительных данных, которых больше нет.
Буфер транзакций Binder имеет ограниченный фиксированный размер, в настоящее время 1 МБ, который используется всеми транзакциями, выполняемыми в процессе. Поскольку это ограничение действует на уровне процесса, а не на уровне каждого действия, эти транзакции включают все транзакции связывания в приложении, такие как onSaveInstanceState, startActivity и любое взаимодействие с системой. При превышении предельного размера создается исключение TransactionTooLargeException.
В конкретном случае saveInstanceState объем данных должен быть небольшим, поскольку системному процессу необходимо сохранять предоставленные данные до тех пор, пока пользователь сможет вернуться к этому действию (даже если процесс действия будет уничтожен). Мы рекомендуем сохранять сохраненное состояние до размера менее 50 тыс. данных.
Примечание. В Android 7.0 (уровень API 24) и более поздних версиях система генерирует исключение TransactionTooLargeException как исключение времени выполнения. В более ранних версиях Android система отображает предупреждение только в logcat.