Сериализация и десериализация — фундаментальные процессы преобразования объектов в формат для передачи или хранения. В мобильной разработке эти механизмы используются при каждом сетевом запросе, сохранении состояния и межпроцессном взаимодействии. По данным MDN Web Docs, 2024, JSON остаётся самым популярным форматом сериализации в вебе и мобильных приложениях, обгоняя XML и Protocol Buffers.
Главное
Сериализация — это процесс преобразования объекта приложения в формат, пригодный для передачи по сети или сохранения на диск. Десериализация выполняет обратное преобразование, восстанавливая объект из полученных данных. В мобильной разработке сериализация применяется в API-запросах, сохранении состояния экрана, кэшировании и передачи данных через Intent или Bundle.
Любое взаимодействие между компонентами приложения или между приложением и сервером требует сериализации. REST API передают данные в JSON или XML, gRPC использует Protocol Buffers, а внутрипроцессное взаимодействие на Android применяет Parcelable. Без сериализации невозможно передать сложный объект через границу процесса или сохранить его в базу данных.
// Общий принцип сериализации
data class User(
val id: Int,
val name: String,
val email: String
)
// Сериализация: объект -> JSON
fun serializeUser(user: User): String {
return """{"id":${user.id},"name":"${user.name}","email":"${user.email}"}"""
}
// Десериализация: JSON -> объект
fun deserializeUser(json: String): User? {
// парсинг JSON в объект
return Gson().fromJson(json, User::class.java)
}
| Формат | Размер | Скорость | Читаемость | Типизация |
|---|---|---|---|---|
| JSON | средний | высокая | высокая | динамическая |
| XML | большой | средняя | высокая | схема XSD |
| Protocol Buffers | малый | очень высокая | низкая | строгая .proto |
| FlatBuffers | малый | максимальная | низкая | строгая .fbs |
JSON (JavaScript Object Notation) — лёгкий текстовый формат, основанный на синтаксисе объектов JavaScript. JSON поддерживает строки, числа, булевы значения, массивы и вложенные объекты, что покрывает большинство сценариев передачи данных в мобильных приложениях. Формат не зависит от платформы: каждая экосистема предоставляет встроенные средства для его парсинга.
JSON выигрывает за счёт простоты и универсальности. Разработчику не нужна схема для базового использования — структура определяется динамически во время парсинга. Читаемость формата упрощает отладку и тестирование: ответ сервера можно просмотреть в любом инструменте разработчика. На обеих мобильных платформах JSON обрабатывается нативно без подключения сторонних библиотек.
// Codable — нативная сериализация JSON в Swift
struct User: Codable {
let id: Int
let name: String
let email: String
}
let jsonString = """{"id":1,"name":"John","email":"john@test.com"}"""
let jsonData = Data(jsonString.utf8)
let decoder = JSONDecoder()
let user = try! decoder.decode(User.self, from: jsonData)
Protocol Buffers (protobuf) — бинарный формат сериализации, разработанный Google для высокопроизводительных систем. В отличие от JSON, protobuf требует предварительного определения схемы в .proto-файле, но обеспечивает значительно меньший размер данных и более высокую скорость обработки. Формат используется в gRPC, Firebase Firestore и внутренних сервисах Google.
Схема protobuf описывает сообщения с типизированными полями, каждое из которых имеет уникальный номер. Компилятор protoc генерирует классы на нужном языке, которые выполняют сериализацию и десериализацию автоматически. Protobuf поддерживает эволюцию схемы через правила добавления и удаления полей без потери обратной совместимости.
// Определение схемы в user.proto
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
string email = 3;
repeated string roles = 4;
}
// Сгенерированный код на Kotlin
val user = UserProto.User.newBuilder()
.setId(1)
.setName("John")
.setEmail("john@test.com")
.build()
val bytes: ByteArray = user.toByteArray()
XML (eXtensible Markup Language) — формат с жёсткой структурой, поддержкой пространств имён и валидацией через XSD-схемы. XML проигрывает JSON в компактности и скорости парсинга, но остаётся востребованным в Android-разработке для layout-файлов, AndroidManifest, ресурсов и конфигураций Gradle. На iOS XML используется в plist-файлах и некоторых legacy-сервисах.
Android предоставляет три способа парсинга XML: DOM (загрузка всего документа в память), SAX (событийно-ориентированный потоковый парсинг) и XmlPullParser (гибридный подход). XmlPullParser — рекомендуемый вариант для мобильных устройств, так как он эффективно работает с ограниченной памятью и позволяет обрабатывать документ по мере чтения.
// XmlPullParser на Android
fun parseUserXml(inputStream: InputStream): User? {
val parser = Xml.newPullParser()
parser.setInput(inputStream, Xml.Encoding.UTF_8.name)
var id: Int? = null
var name: String? = null
var email: String? = null
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.eventType == XmlPullParser.START_TAG
&& parser.name == "email") {
email = parser.nextText()
}
}
return User(id!!, name!!, email!!)
}
Каждая платформа предлагает собственные инструменты для сериализации. На iOS основным механизмом является протокол Codable с JSONEncoder и JSONDecoder, а для Objective-C — NSJSONSerialization. Android использует библиотеки Gson, Moshi и kotlinx.serialization. Для передачи данных между процессами Android применяет Parcelable, а iOS — NSKeyedArchiver. Kotlin-проекты всё чаще выбирают kotlinx.serialization — решение от JetBrains, которое поддерживает мультиплатформенность и не зависит от рефлексии, генерируя сериализаторы на этапе компиляции через плагин компилятора Kotlin.
Android поддерживает два механизма сериализации для Intent и Bundle. Serializable — стандартный Java-механизм, использующий рефлексию, что приводит к низкой производительности. Parcelable — Android-специфичный протокол, требующий ручной реализации методов writeToParcel и createFromParcel, но работающий в десятки раз быстрее за счёт прямого манипулирования байтами.
// Parcelable на Android
@Parcelize
data class UserParcel(
val id: Int,
val name: String,
val email: String
) : Parcelable
// Передача через Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", userParcel)
startActivity(intent)
На iOS для передачи данных между контроллерами используется Codable с предварительной сериализацией в Data, а для межпроцессного взаимодействия — NSKeyedArchiver, который преобразует объекты в бинарный формат Property List. Современные проекты на SwiftUI предпочитают кодировать данные через JSONEncoder для передачи их между модулями приложения.
Некорректная десериализация недоверенных данных может привести к уязвимостям. Атаки через сериализацию эксплуатируют переопределённые методы readObject в Java или небезопасные десериализаторы сторонних библиотек. На Android следует избегать Serializable для данных из ненадёжных источников, используя вместо него Parcelable или ручную валидацию всех полей после десериализации. На iOS JSONDecoder по умолчанию строг к типам, но при работе с JSONSerialization разработчик должен проверять типы через условное приведение.
При выборе формата сериализации учитываются требования к производительности, размеру данных и совместимости. Для REST API и микросервисной архитектуры оптимальным выбором остаётся JSON — он поддерживается всеми платформами и языками. Для высоконагруженных систем и мобильных приложений с ограниченным трафиком предпочтительнее Protocol Buffers, которые обеспечивают меньший размер и более быструю десериализацию. XML оправдан только в конфигурационных сценариях и при интеграции с legacy-системами. В современных проектах также набирает популярность FlatBuffers — бинарный формат без этапа десериализации, используемый в игровых движках и приложениях с минимальными задержками. Каждый формат имеет свою нишу, и грамотный выбор напрямую влияет на скорость работы приложения и объём потребляемого трафика.
Часто задаваемые вопросы
Сериализация — это упаковка объекта приложения в формат, который можно отправить по сети или сохранить в файл. Представьте, что вы фотографируете вещь — фотография это сериализация, а восстановление вещи по фото — десериализация.
JSON — текстовый формат, читаемый человеком и не требующий схемы. Protocol Buffers — бинарный формат с обязательной схемой (.proto), значительно меньшим размером и более высокой скоростью. Protobuf выбирают для высоконагруженных систем, JSON — для универсальной совместимости.
XML остаётся стандартом для конфигурационных файлов (AndroidManifest, layout-ресурсы), документов со сложной вложенностью и систем с жёсткой валидацией через XSD. XML также применяется в SOAP-протоколах и legacy-системах, где требуется поддержка пространств имён.
Codable — протокол Swift, объединяющий Encodable и Decodable для автоматической сериализации и десериализации. Компилятор генерирует реализацию методов encode(to:) и init(from:) для всех свойств структуры или класса.
Parcelable работает значительно быстрее Serializable, поскольку не использует рефлексию и напрямую записывает поля в байтовый поток. На современных устройствах разница может достигать 10-кратного ускорения в пользу Parcelable.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также