Ang Moshi ay isang modernong JSON library mula sa Square, na espesyal na ginawa para sa Kotlin at Android na isinasaalang-alang ang mga limitasyon ng Gson. Ito ay ganap na katugma sa null-safety ng Kotlin, bumubuo ng code sa yugto ng compilation at hindi gumagamit ng reflection, na nagpapataas ng pagganap at pagiging maaasahan. Ayon sa datos ng Square Moshi, 2024, ang Moshi ay nagbibigay ng predictable na serialization at sumusuporta sa custom na adapter para sa anumang uri ng data.
Mga Pangunahing Punto
Moshi ay isang JSON library para sa JVM, Android at Kotlin Multiplatform, na ginawa ng Square (mga lumikha ng OkHttp at Retrofit). Hindi tulad ng Gson, ang Moshi ay hindi umaasa sa reflection — ang mga adapter ay nabubuo sa yugto ng compilation sa pamamagitan ng anotasyong @JsonClass(generateAdapter = true). Ginagawa nitong mas mabilis, mas ligtas at mas predictable ang Moshi sa pagtatrabaho sa mga konstruksyong tiyak sa Kotlin.
Ang pangunahing pagkakaiba ng Moshi sa mga nauna ay ang pagtanggi sa reflection. Reflection ay nagpapahintulot sa Gson na gumana sa anumang klase nang walang paghahanda, ngunit ang kapalit ay mabagal na pagsisimula, kawalan ng kakayahang mag-optimize ng compiler at panganib ng mga pagkakamali sa runtime. Ang Moshi ay nangangailangan ng tahasang pagtukoy ng mga klase para sa code generation, ngunit kapalit ay nagbibigay ng bilis ng sulat-kamay na code at kumpletong kaligtasan ng uri sa yugto ng compilation.
// Pagkonekta ng Moshi sa build.gradle
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"
}
// Simpleng modelo na may code generation
@JsonClass(generateAdapter = true)
data class User(
@Json(name = "user_id")
val id: Int,
val name: String,
val email: String,
val avatar: String? = null
)
// Paggamit
val moshi = Moshi.Builder()
.build()
val jsonAdapter = moshi.adapter(User::class.java)
Upang magsimulang magtrabaho sa Moshi, kailangang magdagdag ng mga dependency sa build.gradle at mag-anotate ng mga modelo. Moshi.Builder ay nagsisilbing entry point: sa pamamagitan nito ay idinaragdag ang mga built-in na adapter para sa mga karaniwang uri, custom na adapter, at kino-configure ang pag-uugali ng library. Ang Moshi ay sumusuporta sa mga adapter para sa Date, Enum, Collection at Map na handa na, ngunit para sa mga klase ng Kotlin kinakailangan ang moshi-kotlin module. Hindi tulad ng Gson, ang Moshi ay hindi gumagamit ng reflection para sa mga klase ng Kotlin bilang default — para dito ay ikinokonekta ang KotlinJsonAdapterFactory, na nagsisilbing backup na opsyon kapag hindi inilalapat ang code generation o ang klase ay hindi na-anotahan ng @JsonClass. Ang ganitong paraan ay ginagarantiyahan na ang developer ay tahasang pumipili sa pagitan ng pagganap ng code generation at flexibility ng reflection para sa bawat partikular na klase.
Pagkatapos buuin ang Moshi sa pamamagitan ng Builder, ang developer ay makakakuha ng instance ng Moshi at humihiling ng adapter para sa nais na klase. JsonAdapter ay ang sentral na bagay na nagsasagawa ng serialization sa pamamagitan ng toJson() at deserialization sa pamamagitan ng fromJson(). Awtomatikong ginagamit ng Moshi ang nabuong adapter kung ang klase ay na-anotahan ng @JsonClass(generateAdapter = true), kung hindi, inilalapat nito ang reflective KotlinJsonAdapterFactory bilang backup na opsyon. Pinagsasama ng pamamaraang ito ang bilis ng code generation sa flexibility ng reflective mechanism para sa mga proyekto ng anumang sukat at antas ng pagiging kumplikado. Ang Moshi ay angkop para sa parehong maliliit na application at malalaking proyekto ng korporasyon na may daan-daang mga modelo ng data.
// Pag-configure ng Moshi gamit ang KotlinJsonAdapterFactory
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.add(LocalDateAdapter())
.build()
// Paggamit ng adapter
val adapter = moshi.adapter(User::class.java)
// Serialization
val user = User(1, "Alice", "alice@test.com")
val json = adapter.toJson(user)
// Deserialization
val jsonString = """{"user_id":2,"name":"Bob","email":"bob@test.com"}"""
val parsedUser = adapter.fromJson(jsonString)
// Pagtatrabaho sa listahan
val listAdapter = moshi.adapter(
Types.newParameterizedType(
List::class.java,
User::class.java
)
)
Moshi ay gumagamit ng mga anotasyon para i-configure ang serialization at suportahan ang mga custom na uri. @Json(name = "...") ay nagtatakda ng JSON key para sa field. @Transient ay nagbubukod ng field mula sa serialization. @JsonClass(generateAdapter = true) ay nagpapagana ng code generation. Para sa custom na lohika, ang Moshi ay nagbibigay ng mga anotasyong @ToJson at @FromJson, na maaaring ilagay sa isang hiwalay na klase ng adapter.
Ang anotasyong @Json ay pumapalit sa @SerializedName ng Gson at gumagana nang katulad: ang field na kotlinName ay nakaugnay sa JSON key na “kotlin_name”. Para sa mga uri na hindi ma-serialize ng Moshi bilang default (hal. LocalDate), ang developer ay lumilikha ng klase na may mga pamamaraang @ToJson at @FromJson. Mga Adapter ay nirerehistro sa pamamagitan ng Moshi.Builder.add() at inilalapat nang global o para sa isang partikular na uri. Sinusuportahan ng Moshi ang sealed class at polymorphic serialization sa pamamagitan ng @JsonClass na may tahasang pagtukoy ng discriminator, na nagpapahintulot sa pagtatrabaho sa mga hierarchy ng uri sa JSON nang walang manu-manong pagsusuri ng field. Sa deserialization, ang Moshi ay binabalewala ang mga hindi kilalang key sa JSON bilang default, na tinitiyak ang backward compatibility kapag nagdaragdag ng mga bagong field sa panig ng server nang hindi binabago ang code ng kliyente. Para sa debugging, maaaring i-activate ang strict mode sa pamamagitan ng failOnUnknown, na nagtatapon ng exception kapag may nakitang hindi kilalang key.
// Custom na adapter para sa LocalDate
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)
}
}
// Modelo na may mga anotasyon ng Moshi
@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
)
// Pagrehistro ng adapter
val moshi = Moshi.Builder()
.add(LocalDateAdapter())
.add(KotlinJsonAdapterFactory())
.build()
Ang paghahambing ng Moshi at Gson ay isang karaniwang tanong kapag pumipili ng JSON library para sa isang Android project. Moshi ay nananalo sa modernong pag-unlad ng Kotlin dahil sa code generation, null-safety at bilis. Ang Gson ay nananatiling may-katuturan para sa mga proyekto ng Java, legacy na code at mga senaryo kung saan mahalaga ang minimal na konfigurasyon. Ang pagkakaiba ay nagiging kapansin-pansin sa malalaking volume ng data at kumplikadong mga modelo.
Ang mga pagsubok sa pagganap ay nagpapakita na ang Moshi na may code generation ay gumagana nang 2-5 beses na mas mabilis kaysa sa Gson sa mga operasyon ng serialization at deserialization. Ang pangunahing bentahe ng Moshi ay ang tamang paghawak ng Kotlin null-safety: kung ang isang field ay wala sa JSON at sa modelo ay idineklara bilang non-null na walang default na halaga, ang Moshi ay nagtatapon ng exception sa yugto ng deserialization, na pumipigil sa mga nakatagong error.
| Katangian | Gson | Moshi |
|---|---|---|
| Mekanismo | reflection | code generation / reflection |
| Null safety | hindi isinasaalang-alang | buong suporta sa Kotlin |
| Bilis | katamtaman | mataas |
| Mga default na halaga | hindi sinusuportahan | sinusuportahan |
| Kotlin Multiplatform | hindi | oo |
| Sukat ng library | ~240 Kb | ~150 Kb |
Ang pagpili sa pagitan ng Moshi at Gson ay depende sa konteksto ng proyekto. Mga bagong proyekto sa Kotlin ay nakikinabang sa Moshi dahil sa kaligtasan ng uri at pagganap. Ang Gson ay nananatiling isang makatwirang pagpipilian para sa suporta ng Java code, mga dynamic na istraktura ng JSON o kapag ang pagiging simple ng koneksyon ay mas mahalaga kaysa sa bilis. Para sa Kotlin Multiplatform, ang Moshi ay ang isa lamang sa dalawang variant na sumusuporta sa platform na ito.
Sa paglipat mula Gson patungong Moshi, ang mga pangunahing pagbabago ay may kinalaman sa mga anotasyon at adapter. Ang @SerializedName ng Gson ay pinalitan ng @Json(name = "..."), at ang custom na JsonSerializer/JsonDeserializer — ng pares na @ToJson/@FromJson. Para sa mga modelo na may mga default na halaga at nullable na field, ang Moshi ay kumikilos nang mas predictable: kung ang isang non-null na field na walang default na halaga ay wala sa JSON, ang Moshi ay nagtatapon ng JsonDataException, na pumipigil sa mga nakatagong NPE. Ang integrasyon sa Retrofit sa pamamagitan ng MoshiConverterFactory ay idinaragdag sa isang dependency at hindi nangangailangan ng pagbabago sa arkitektura ng network layer. Para sa obfuscation sa pamamagitan ng ProGuard o R8, kailangang magdagdag ng mga panuntunan para sa pagpapanatili ng mga klase na na-anotahan ng @JsonClass at mga nabuong adapter, kung hindi, masisira ang serialization sa release build. Sa pangkalahatan, ang paglipat mula Gson patungong Moshi ay makatwiran sa mga bagong proyekto ng Kotlin kung saan mahalaga ang pagganap at kaligtasan ng uri.
// Paghahambing ng serialization: Gson vs Moshi
data class Sample(
val name: String,
val count: Int,
val tags: List<String> = listOf()
)
// Gson: gumagana sa pamamagitan ng reflection
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
Sample::class.java)
// count = 0 (default), ngunit ang null-safety ay hindi sinusuri
// Moshi: nangangailangan ng adapter, ang null-safety ay tahas
@JsonClass(generateAdapter = true)
data class SampleMoshi(
val name: String,
val count: Int,
val tags: List<String> = listOf()
)
Mga Madalas Itanong
Moshi ay isang JSON library mula sa Square para sa Kotlin at Android na gumagamit ng code generation sa halip na reflection. Nagbibigay ito ng mataas na pagganap, tamang paghawak ng null-safety ng Kotlin at pagiging tugma sa Kotlin Multiplatform.
Nalampasan ng Moshi ang Gson sa bilis (2-5 beses na mas mabilis dahil sa code generation), kaligtasan (isinasaalang-alang ang null anotasyon ng Kotlin) at laki (~90 Kb mas maliit). Moshi ay sumusuporta din sa Kotlin Multiplatform at mga default na halaga sa data class.
@JsonClass(generateAdapter = true) ay nag-uutos sa Moshi na bumuo ng adapter para sa klase na ito sa yugto ng compilation. Ang nabuong adapter ay nagsasagawa ng serialization nang direkta, walang reflection, na nagbibigay ng maximum na pagganap.
Gumawa ng klase na may mga pamamaraan na na-anotahan ng @ToJson (serialization) at @FromJson (deserialization). Irehistro ang instance sa pamamagitan ng Moshi.Builder.add(). Awtomatikong hahanapin at ilalapat ng Moshi ang adapter kapag nagtatrabaho sa kaukulang uri.
Oo, Moshi ay sumusuporta sa Kotlin Multiplatform mula sa bersyon 1.13.0. Ginagawa nitong ang tanging sikat na solusyon sa JSON para sa mga proyekto ng KMP, na nagpapahintulot sa paggamit ng karaniwang code ng serialization sa lahat ng target na platform.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din