Moshi — Square tomonidan Gson cheklovlarini hisobga olgan holda Kotlin va Android uchun maxsus yaratilgan zamonaviy JSON kutubxonasi. U Kotlinning null-xavfsizligi bilan to‘liq mos keladi, kompilyatsiya bosqichida kod yaratadi va reflektiyadan foydalanmaydi, bu esa samaradorlik va ishonchlilikni oshiradi. Square Moshi, 2024 ma‘lumotlariga ko‘ra, Moshi bashorat qilinadigan serializatsiyani ta‘minlaydi va har qanday ma‘lumot turlari uchun maxsus adapterlarni qo‘llab-quvvatlaydi.
Asosiy fikrlar
Moshi — Square (OkHttp va Retrofit mualliflari) tomonidan yaratilgan JVM, Android va Kotlin Multiplatform uchun JSON kutubxonasi. Gsondan farqli o‘laroq, Moshi reflektiyaga tayanmaydi — adapterlar @JsonClass(generateAdapter = true) annotatsiyasi orqali kompilyatsiya bosqichida yaratiladi. Bu Moshi-ni Kotlin-spesifik konstruksiyalar bilan ishlashda tezroq, xavfsizroq va bashorat qilinadigan qiladi.
Moshining o‘tmishdoshlardan asosiy farqi — reflektiyadan voz kechishdir. Reflektiya Gsonga hech qanday tayyorgarliksiz istalgan sinf bilan ishlashga imkon beradi, ammo evaziga sekin ishga tushirish, kompilyator tomonidan optimallashtirishning imkonsizligi va ish vaqtida xato xavfi mavjud. Moshi kod generatsiyasi uchun sinflarni aniq ko‘rsatishni talab qiladi, ammo evaziga qo‘lda yozilgan kod tezligi va kompilyatsiya bosqichida to‘liq tip xavfsizligini beradi.
// Moshini build.gradle-ga ulash
dependencies {
implementation "com.squareup.moshi:moshi:1.15.0"
implementation "com.squareup.moshi:moshi-kotlin:1.15.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.15.0"
}
// Kod generatsiyasi bilan oddiy model
@JsonClass(generateAdapter = true)
data class User(
@Json(name = "user_id")
val id: Int,
val name: String,
val email: String,
val avatar: String? = null
)
// Foydalanish
val moshi = Moshi.Builder()
.build()
val jsonAdapter = moshi.adapter(User::class.java)
Moshi bilan ishlashni boshlash uchun build.gradle-ga bog‘liqliklarni qo‘shish va modellarni annotatsiya qilish kerak. Moshi.Builder kirish nuqtasi sifatida xizmat qiladi: u orqali standart turlar uchun o‘rnatilgan adapterlar, maxsus adapterlar qo‘shiladi va kutubxona xatti-harakati sozlanadi. Moshi Date, Enum, Collection va Map uchun adapterlarni qutidan chiqqandek qo‘llab-quvvatlaydi, lekin Kotlin sinflari uchun moshi-kotlin moduli talab qilinadi. Gsondan farqli o‘laroq, Moshi Kotlin sinflari uchun standart sifatida reflektiyadan foydalanmaydi — buning uchun KotlinJsonAdapterFactory ulanadi, u kod generatsiyasi qo‘llanilmaganda yoki sinf @JsonClass bilan annotatsiya qilinmaganda zaxira variant sifatida xizmat qiladi. Bunday yondashuv dasturchining har bir aniq sinf uchun kod generatsiyasi samaradorligi va reflektiya moslashuvchanligi o‘rtasida aniq tanlov qilishini kafolatlaydi.
Builder orqali Moshi qurilgandan so‘ng, dasturchi Moshi nusxasini oladi va kerakli sinf uchun adapter so‘raydi. JsonAdapter — toJson() orqali serializatsiya va fromJson() orqali deserializatsiyani bajaradigan markaziy ob‘ektdir. Moshi sinf @JsonClass(generateAdapter = true) bilan annotatsiya qilingan bo‘lsa, avtomatik ravishda yaratilgan adapterdan foydalanadi, aks holda zaxira variant sifatida reflektiv KotlinJsonAdapterFactory-ni qo‘llaydi. Bu yondashuv kod generatsiyasi tezligini istalgan miqyosdagi va murakkablik darajasidagi loyihalar uchun reflektiv mexanizmning moslashuvchanligi bilan birlashtiradi. Moshi kichik ilovalar uchun ham, yuzlab ma‘lumot modellariga ega yirik korporativ loyihalar uchun ham juda mos keladi.
// Moshini KotlinJsonAdapterFactory bilan sozlash
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.add(LocalDateAdapter())
.build()
// Adapterdan foydalanish
val adapter = moshi.adapter(User::class.java)
// Serializatsiya
val user = User(1, "Alice", "alice@test.com")
val json = adapter.toJson(user)
// Deserializatsiya
val jsonString = """{"user_id":2,"name":"Bob","email":"bob@test.com"}"""
val parsedUser = adapter.fromJson(jsonString)
// Ro‘yxat bilan ishlash
val listAdapter = moshi.adapter(
Types.newParameterizedType(
List::class.java,
User::class.java
)
)
Moshi serializatsiyani sozlash va maxsus turlarni qo‘llab-quvvatlash uchun annotatsiyalardan foydalanadi. @Json(name = "...") maydon uchun JSON kalitini o‘rnatadi. @Transient maydonni serializatsiyadan chiqarib tashlaydi. @JsonClass(generateAdapter = true) kod generatsiyasini yoqadi. Maxsus mantiq uchun Moshi alohida adapter sinfida joylashtirilishi mumkin bo‘lgan @ToJson va @FromJson annotatsiyalarini taqdim etadi.
@Json annotatsiyasi Gsonning @SerializedName o‘rnini bosadi va xuddi shunday ishlaydi: kotlinName maydoni JSON kaliti “kotlin_name” bilan bog‘lanadi. Moshi standart sifatida serializatsiya qila olmaydigan turlar uchun (masalan, LocalDate) dasturchi @ToJson va @FromJson metodlari bilan sinf yaratadi. Adapterlar Moshi.Builder.add() orqali ro‘yxatdan o‘tkaziladi va global yoki ma‘lum bir turga qo‘llaniladi. Moshi sealed class va diskriminatorning aniq ko‘rsatkichi bilan @JsonClass orqali polimorf serializatsiyani qo‘llab-quvvatlaydi, bu maydonlarni qo‘lda tekshirmasdan JSON-da tip ierarxiyalari bilan ishlashga imkon beradi. Deserializatsiya paytida Moshi standart sifatida JSON-dagi noma‘lum kalitlarni e‘tiborsiz qoldiradi, bu server tomonida yangi maydonlar qo‘shilganda mijoz kodini o‘zgartirmasdan orqaga qarab moslikni ta‘minlaydi. Nosozliklarni tuzatish uchun failOnUnknown orqali qattiq rejimni yoqish mumkin, u noma‘lum kalitlar aniqlanganda istisno tashlaydi.
// LocalDate uchun maxsus adapter
class LocalDateAdapter {
@ToJson
fun toJson(date: LocalDate): String {
return date.format(DateTimeFormatter.ISO_LOCAL_DATE)
}
@FromJson
fun fromJson(dateString: String): LocalDate {
return LocalDate.parse(dateString)
}
}
// Moshi annotatsiyalari bilan model
@JsonClass(generateAdapter = true)
data class Event(
@Json(name = "event_id")
val id: Int,
@Json(name = "event_date")
val date: LocalDate,
@Transient
val localCache: String? = null
)
// Adapter ro‘yxatdan o‘tkazish
val moshi = Moshi.Builder()
.add(LocalDateAdapter())
.add(KotlinJsonAdapterFactory())
.build()
Moshi va Gsonni solishtirish Android loyihasi uchun JSON kutubxonasini tanlashda tez-tez so‘raladigan savoldir. Moshi kod generatsiyasi, null-xavfsizligi va tezligi tufayli zamonaviy Kotlin ishlanmasida g‘alaba qozonadi. Gson Java loyihalari, eski kod va minimal konfiguratsiya muhim bo‘lgan stsenariylar uchun dolzarb bo‘lib qoladi. Farq katta hajmdagi ma‘lumotlar va murakkab modellarda sezilarli bo‘ladi.
Samaradorlik testlari shuni ko‘rsatadiki, kod generatsiyasi bilan Moshi serializatsiya va deserializatsiya operatsiyalarida Gsondan 2-5 marta tezroq ishlaydi. Moshining asosiy afzalligi — Kotlin null-xavfsizligini to‘g‘ri qayta ishlash: agar JSON-da maydon bo‘lmasa va modelda u standart qiymatsiz non-null deb e‘lon qilingan bo‘lsa, Moshi deserializatsiya bosqichida istisno tashlab, yashirin xatolarning oldini oladi.
| Xususiyat | Gson | Moshi |
|---|---|---|
| Mexanizm | reflektiya | kod generatsiyasi / reflektiya |
| Null safety | hisobga olmaydi | to‘liq Kotlin qo‘llab-quvvatlash |
| Tezlik | o‘rtacha | yuqori |
| Standart qiymatlar | qo‘llab-quvvatlamaydi | qo‘llab-quvvatlaydi |
| Kotlin Multiplatform | yo‘q | ha |
| Kutubxona hajmi | ~240 Kb | ~150 Kb |
Moshi va Gson o‘rtasidagi tanlov loyiha kontekstiga bog‘liq. Kotlin-dagi yangi loyihalar tip xavfsizligi va samaradorlik tufayli Moshidan foyda oladi. Gson Java kodini qo‘llab-quvvatlash, dinamik JSON tuzilmalari yoki ulanish soddaligi tezlikdan muhimroq bo‘lgan hollarda oqilona tanlov bo‘lib qoladi. Kotlin Multiplatform uchun Moshi bu platformani qo‘llab-quvvatlovchi ikkita variantdan yagona hisoblanadi.
Gsondan Moshiga migratsiya paytida asosiy o‘zgarishlar annotatsiyalar va adapterlarga tegishli. Gsonning @SerializedName @Json(name = "...") bilan, maxsus JsonSerializer/JsonDeserializer esa @ToJson/@FromJson juftligi bilan almashtiriladi. Standart qiymatlar va nullable maydonlari bo‘lgan modellar uchun Moshi bashorat qilinadiganroq harakat qiladi: agar JSON-da standart qiymatsiz non-null maydon bo‘lmasa, Moshi JsonDataException tashlab, yashirin NPEning oldini oladi. Retrofit bilan MoshiConverterFactory orqali integratsiya bitta bog‘liqlik bilan qo‘shiladi va tarmoq qatlami arxitekturasini o‘zgartirishni talab qilmaydi. ProGuard yoki R8 orqali obfuskatsiya uchun @JsonClass annotatsiyalangan sinflar va yaratilgan adapterlarni saqlash qoidalarini qo‘shish kerak, aks holda serializatsiya release versiyasida buziladi. Umuman olganda, Gsondan Moshiga migratsiya samaradorlik va tip xavfsizligi muhim bo‘lgan yangi Kotlin loyihalarida asoslanadi.
// Serializatsiya solishtiruvi: Gson vs Moshi
data class Sample(
val name: String,
val count: Int,
val tags: List<String> = listOf()
)
// Gson: reflektiya orqali ishlaydi
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
Sample::class.java)
// count = 0 (default), lekin null-xavfsizlik tekshirilmaydi
// Moshi: adapter talab qiladi, null-xavfsizlik aniq
@JsonClass(generateAdapter = true)
data class SampleMoshi(
val name: String,
val count: Int,
val tags: List<String> = listOf()
)
Tez-tez so‘raladigan savollar
Moshi — Square-dan Kotlin va Android uchun reflektiya o‘rniga kod generatsiyasidan foydalanadigan JSON kutubxonasi. U yuqori samaradorlik, Kotlin null-xavfsizligini to‘g‘ri qayta ishlash va Kotlin Multiplatform bilan moslikni ta‘minlaydi.
Moshi Gsonni tezlikda (kod generatsiyasi tufayli 2-5 marta tezroq), xavfsizlikda (Kotlin null-annotatsiyalarini hisobga oladi) va hajmda (~90 Kb kichikroq) ortda qoldiradi. Moshi shuningdek, Kotlin Multiplatform va data class da standart qiymatlarni qo‘llab-quvvatlaydi.
@JsonClass(generateAdapter = true) Moshiga kompilyatsiya bosqichida ushbu sinf uchun adapter yaratishni buyuradi. Yaratilgan adapter serializatsiyani to‘g‘ridan-to‘g‘ri, reflektiyasiz bajaradi, bu maksimal samaradorlikni beradi.
@ToJson (serializatsiya) va @FromJson (deserializatsiya) bilan annotatsiyalangan metodlari bo‘lgan sinf yarating. Nusxani Moshi.Builder.add() orqali ro‘yxatdan o‘tkazing. Moshi tegishli tur bilan ishlashda avtomatik ravishda adapterni topib qo‘llaydi.
Ha, Moshi 1.13.0 versiyasidan boshlab Kotlin Multiplatform-ni qo‘llab-quvvatlaydi. Bu uni KMP loyihalari uchun yagona mashhur JSON yechimiga aylantiradi va barcha maqsadli platformalarda umumiy serializatsiya kodidan foydalanish imkonini beradi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.
Shuningdek o'qing