Как передать объект между Activity через Intent в Android
Что проверяют
Знаете ли вы, что через Intent уходит не сам объект, а его сериализованная копия, и чем это ограничено. Следом спрашивают, почему Parcelable, а не Serializable, и как быть с большими данными.
Как отвечать
Объект кладётся в extras, они сериализуются в Bundle и уходят через Binder в системный процесс и обратно. Варианты:
Parcelable: основной способ. В Kotlin его не пишут руками: плагинkotlin-parcelizeи аннотация@Parcelizeсами генерируютwriteToParcelиCREATOR;Serializable: работает, но через рефлексию, медленнее и создаёт больше мусора. Годится разве что для простых классов из общего модуля;- чтение:
intent.getParcelableExtra("user")устарел с API 33, новая версия принимает класс:getParcelableExtra("user", User::class.java). Чтобы не ветвиться по версиям, используйтеIntentCompat.getParcelableExtraиз androidx.core; - передача ID: во многих случаях это и есть правильный ответ. Передаёте
userId, а экран сам загружает данные из репозитория или Room. Так данные не устаревают и не упираются в размер.
Если приложение на одной Activity с Navigation, экранами становятся фрагменты или composable, и аргументы передают через Safe Args или типобезопасные маршруты на kotlinx.serialization. Общий ViewModel подходит для экранов одного графа.
Результат обратно получают через Activity Result API: registerForActivityResult вместо устаревшего startActivityForResult.
Где спотыкаются
Кладут в Intent большой список или Bitmap. Буфер Binder около 1 МБ на процесс, и приложение падает с TransactionTooLargeException, иногда только на части устройств.
Думают, что вторая Activity получила ту же ссылку. Это копия: её изменения первая Activity не увидит, вернуть их можно только через результат.
При ручной реализации Parcelable пишут и читают поля в разном порядке. Компилятор этого не заметит, а данные тихо перемешаются. Близкая ошибка: передать объект через статическое поле. После смерти процесса оно обнулится, а extras система восстанавливает сама.