Серіалізація та десеріалізація — фундаментальні процеси перетворення об'єктів у формат для передачі або зберігання. У мобільній розробці ці механізми використовуються при кожному мережевому запиті, збереженні стану та міжпроцесній взаємодії. За даними 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також