Serializarea și deserializarea sunt procese fundamentale de transformare a obiectelor într-un format pentru transmitere sau stocare. În dezvoltarea mobilă, aceste mecanisme sunt utilizate la fiecare cerere de rețea, salvare a stării și comunicare interproces. Potrivit MDN Web Docs, 2024, JSON rămâne cel mai popular format de serializare în web și aplicațiile mobile, depășind XML și Protocol Buffers.
Principalele
Serializarea este procesul de transformare a obiectului aplicației într-un format potrivit pentru transmiterea prin rețea sau salvarea pe disc. Deserializarea realizează transformarea inversă, restaurând obiectul din datele primite. În dezvoltarea mobilă, serializarea se aplică în cererile API, salvarea stării ecranului, stocarea în cache și transmiterea datelor prin Intent sau Bundle.
Orice interacțiune între componentele aplicației sau între aplicație și server necesită serializare. REST API transmit date în JSON sau XML, gRPC utilizează Protocol Buffers, iar comunicarea intraproces pe Android folosește Parcelable. Fără serializare, nu se poate transmite un obiect complex peste granița procesului sau salva în baza de date.
// Principiul general al serializării
data class User(
val id: Int,
val name: String,
val email: String
)
// Serializarea: obiect -> JSON
fun serializeUser(user: User): String {
return """{"id":${user.id},"name":"${user.name}","email":"${user.email}"}"""
}
// Deserializarea: JSON -> obiect
fun deserializeUser(json: String): User? {
// parsarea JSON în obiect
return Gson().fromJson(json, User::class.java)
}
| Format | Dimensiune | Viteză | Lizibilitate | Tipizare |
|---|---|---|---|---|
| JSON | mediu | ridicată | ridicată | dinamică |
| XML | mare | medie | ridicată | schemă XSD |
| Protocol Buffers | mic | foarte ridicată | scăzută | strictă .proto |
| FlatBuffers | mic | maximă | scăzută | strictă .fbs |
JSON (JavaScript Object Notation) este un format text ușor bazat pe sintaxa obiectelor JavaScript. JSON suportă șiruri de caractere, numere, valori booleene, tablouri și obiecte imbricate, acoperind majoritatea scenariilor de transmitere a datelor în aplicațiile mobile. Formatul este independent de platformă: fiecare ecosistem oferă instrumente încorporate pentru parsarea sa.
JSON câștigă datorită simplității și universalității. Dezvoltatorul nu are nevoie de o schemă pentru utilizarea de bază — structura se determină dinamic în timpul parsării. Lizibilitatea formatului simplifică depanarea și testarea: răspunsul serverului poate fi vizualizat în orice instrument de dezvoltare. Pe ambele platforme mobile, JSON se procesează nativ fără a conecta biblioteci externe.
// Codable — serializarea nativă JSON în 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) este un format de serializare binar, dezvoltat de Google pentru sisteme de înaltă performanță. Spre deosebire de JSON, protobuf necesită definirea prealabilă a schemei în fișierul .proto, dar asigură o dimensiune semnificativ mai mică a datelor și o viteză mai mare de procesare. Formatul este utilizat în gRPC, Firebase Firestore și serviciile interne Google.
Schema protobuf descrie mesaje cu câmpuri tipizate, fiecare având un număr unic. Compilatorul protoc generează clase în limba dorită, care realizează automat serializarea și deserializarea. Protobuf suportă evoluția schemei prin reguli de adăugare și eliminare a câmpurilor fără pierderea compatibilității inverse.
// Definirea schemei în user.proto
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
string email = 3;
repeated string roles = 4;
}
// Cod generat în Kotlin
val user = UserProto.User.newBuilder()
.setId(1)
.setName("John")
.setEmail("john@test.com")
.build()
val bytes: ByteArray = user.toByteArray()
XML (eXtensible Markup Language) este un format cu structură strictă, suport pentru spații de nume și validare prin scheme XSD. XML pierde în fața JSON în ceea ce privește compactitatea și viteza de parsare, dar rămâne solicitat în dezvoltarea Android pentru fișierele layout, AndroidManifest, resurse și configurații Gradle. Pe iOS, XML este utilizat în fișierele plist și unele servicii mai vechi.
Android oferă trei metode de parsare XML: DOM (încărcarea întregului document în memorie), SAX (parsare orientată pe evenimente în flux) și XmlPullParser (abordare hibridă). XmlPullParser este varianta recomandată pentru dispozitivele mobile, deoarece funcționează eficient cu memoria limitată și permite procesarea documentului pe măsură ce este citit.
// XmlPullParser pe 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!!)
}
Fiecare platformă oferă propriile instrumente pentru serializare. Pe iOS, mecanismul principal este protocolul Codable cu JSONEncoder și JSONDecoder, iar pentru Objective-C — NSJSONSerialization. Android utilizează bibliotecile Gson, Moshi și kotlinx.serialization. Pentru transmiterea datelor între procese, Android folosește Parcelable, iar iOS — NSKeyedArchiver. Proiectele Kotlin aleg tot mai des kotlinx.serialization — soluția de la JetBrains, care suportă multi-platformă și nu depinde de reflexie, generând serializatoare în etapa de compilare printr-un plugin al compilatorului Kotlin.
Android suportă două mecanisme de serializare pentru Intent și Bundle. Serializable este mecanismul standard Java care utilizează reflexia, ceea ce duce la o performanță scăzută. Parcelable este un protocol specific Android, care necesită implementarea manuală a metodelor writeToParcel și createFromParcel, dar funcționează de zeci de ori mai rapid datorită manipulării directe a octeților.
// Parcelable pe Android
@Parcelize
data class UserParcel(
val id: Int,
val name: String,
val email: String
) : Parcelable
// Transmiterea prin Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", userParcel)
startActivity(intent)
Pe iOS pentru transmiterea datelor între controlere se utilizează Codable cu serializare prealabilă în Data, iar pentru comunicarea interproces — NSKeyedArchiver, care transformă obiectele în formatul binar Property List. Proiectele moderne în SwiftUI preferă codarea datelor prin JSONEncoder pentru transmiterea lor între modulele aplicației.
Deserializarea incorectă a datelor nesigure poate duce la vulnerabilități. Atacurile prin serializare exploatează metodele suprascrise readObject în Java sau deserializatoarele nesigure ale bibliotecilor terțe. Pe Android, trebuie evitat Serializable pentru datele din surse nesigure, folosind în schimb Parcelable sau validarea manuală a tuturor câmpurilor după deserializare. Pe iOS, JSONDecoder este strict în mod implicit față de tipuri, dar la lucrul cu JSONSerialization dezvoltatorul trebuie să verifice tipurile prin conversie condiționată.
La alegerea formatului de serializare se iau în considerare cerințele de performanță, dimensiunea datelor și compatibilitatea. Pentru REST API și arhitectura microserviciilor, alegerea optimă rămâne JSON — este suportat de toate platformele și limbajele. Pentru sistemele cu încărcare mare și aplicațiile mobile cu trafic limitat, sunt preferate Protocol Buffers, care asigură dimensiune mai mică și deserializare mai rapidă. XML este justificat doar în scenarii de configurare și la integrarea cu sistemele legacy. În proiectele moderne, câștigă popularitate și FlatBuffers — format binar fără etapă de deserializare, utilizat în motoarele de jocuri și aplicațiile cu latență minimă. Fiecare format are nișa sa, iar alegerea corectă influențează direct viteza de funcționare a aplicației și volumul de trafic consumat.
Întrebări frecvente
Serializarea este ambalarea obiectului aplicației într-un format care poate fi trimis prin rețea sau salvat în fișier. Imaginați-vă că fotografiați un obiect — fotografia este serializarea, iar restaurarea obiectului după fotografie este deserializarea.
JSON este un format text lizibil pentru om care nu necesită o schemă. Protocol Buffers este un format binar cu schemă obligatorie (.proto), dimensiune semnificativ mai mică și viteză mai mare. Protobuf este ales pentru sistemele cu încărcare mare, JSON — pentru compatibilitate universală.
XML rămâne standardul pentru fișierele de configurare (AndroidManifest, resurse layout), documentele cu structură complexă și sistemele cu validare strictă prin XSD. XML se aplică și în protocoalele SOAP și sistemele legacy unde este necesar suportul pentru spații de nume.
Codable este un protocol Swift care combină Encodable și Decodable pentru serializare și deserializare automată. Compilatorul generează implementarea metodelor encode(to:) și init(from:) pentru toate proprietățile structurii sau clasei.
Parcelable funcționează semnificativ mai rapid decât Serializable, deoarece nu utilizează reflexia și scrie direct câmpurile în fluxul de octeți. Pe dispozitivele moderne, diferența poate atinge o accelerare de 10 ori în favoarea Parcelable.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și