Серијализација и десеријализација су фундаментални процеси претварања објеката у формат за пренос или складиштење. У мобилном развоју, ови механизми се користе при сваком мрежном захтеву, чувању стања и међупроцесној комуникацији. Према 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 датотекама и неким старијим сервисима.
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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође