Компоненты платформы Android
Кирпичи Jetpack, из которых собирают Android-приложение — Navigation с бэкстеком и deep link, Room поверх голого SQLite, Parcelable против Serializable и View Binding после отказа от Kotlin-синтетики.
6 вопросов
MiddleТеорияОчень частоЧто заменяет View Binding и почему Fragment обязан обнулять binding в onDestroyView?
Что заменяет View Binding и почему Fragment обязан обнулять binding в onDestroyView?
Он генерирует типизированный binding-класс на каждую разметку, заменяя findViewById и удалённую Kotlin-синтетику. У Fragment в бэкстеке view уничтожается, а сам объект живёт дальше, поэтому binding, переживший onDestroyView, держит мёртвое дерево view — это утечка.
Типичные ошибки
- ✗Считать, что Fragment и его view уничтожаются вместе и потому binding не может течь
- ✗Принимать обнуление за соглашение линтера, а не за лечение реально удержанного дерева view
- ✗Думать, что View Binding — рантайм-кэш, а не сгенерированный типизированный класс
Уточняющие вопросы
- →Почему Fragment в бэкстеке вообще переживает собственную view?
- →Чем
viewLifecycleOwnerотличается от lifecycle owner самого Fragment?
MiddleТеорияЧастоВ вашей Room-entity есть вложенный объект. Можно ли просто хранить его байты из Parcel как BLOB?
В вашей Room-entity есть вложенный объект. Можно ли просто хранить его байты из Parcel как BLOB?
Нет. Parcel — живой буфер IPC, а не формат хранения: его раскладка — деталь реализации и может измениться между релизами, поэтому сохранённые байты могут не прочитаться. Средства Room — это @Embedded, раскладывающий объект по колонкам, и TypeConverter.
Типичные ошибки
- ✗Принимать
Parcelза долговечный формат сериализации, а не за временный буфер IPC - ✗Тянуться к
@Parcelizeна entity вместо@EmbeddedилиTypeConverter - ✗Считать, что Room не умеет хранить вложенный объект без ручной раскладки по колонкам
Уточняющие вопросы
- →Когда вы выберете
TypeConverterвместо@Embeddedдля того же вложенного типа? - →Что сломается на следующем обновлении, если форма сохранённого кодирования изменится?
JuniorТеорияИногдаПочему Android передаёт объекты как Parcelable, а не через Serializable из Java?
Почему Android передаёт объекты как Parcelable, а не через Serializable из Java?
Serializable — интерфейс-маркер: JVM обходит граф объекта рефлексией и активно выделяет память, поэтому медленно. Parcelable пишет поля в Parcel явно, без рефлексии, и потому заметно быстрее. @Parcelize генерирует эту обвязку по свойствам конструктора.
Типичные ошибки
- ✗Думать, что
Parcelableтоже работает рефлексией и отличается лишь форматом - ✗Считать, что выигрыш в скорости даёт сжатие, а не отказ от рефлексии
- ✗Полагать, что эти два взаимозаменяемы и на Android работают одинаково
Уточняющие вопросы
- →Какие типы свойств
@Parcelizeпишет вParcelбез дополнительной помощи? - →Почему
Parcelнельзя писать на диск или отправлять по сети?
JuniorТеорияИногдаЧто даёт Room такого, чего не даёт голый API SQLiteOpenHelper?
Что даёт Room такого, чего не даёт голый API SQLiteOpenHelper?
Room — надстройка над той же SQLite, работающая на компиляции. Он сверяет каждый @Query со схемой на сборке, отображает строки на ваши entity-классы, так что циклов по Cursor нет, и генерирует DAO. А ещё он отказывается делать запрос на главном потоке.
Типичные ошибки
- ✗Думать, что Room заменяет SQLite, а не генерирует код поверх неё
- ✗Считать, что
@Queryпроверяется в рантайме, а не во время компиляции - ✗Полагать, что Room разрешает по-прежнему ходить в базу с главного потока
Уточняющие вопросы
- →Как заставить метод DAO возвращать результат асинхронно?
- →Что происходит с базой, когда у entity появляется новая колонка?