Android Kotlin Json 的序列化和反序列化(使用 Gson 套件)

加入依賴套件

在 build.gradle(Module :app) 中加入 gson 套件
    
dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}
    

如果是新的 build.gradle.kts(Module :app) 的話則是:
    
dependencies {
    implementation ("com.google.code.gson:gson:2.8.9")
}
    

基本使用範例

這裡有一個示範用的 json
    
{
  "id": 1,
  "name": "小明",
  "address": null
}
    

在 kotlin 中建立對應的 data class,如果 json 中的屬性名稱和 kotlin data class 的屬性名稱一樣的話就可以省略 SerializedName 註解(annotations)
    
import com.google.gson.annotations.SerializedName

data class User(
    @SerializedName("id") val id: Int,
    @SerializedName("name") val name: String,
    @SerializedName("address") val address: String?
)
    

反序列化(deserialization)

將 json 內容塞到物件中:
    
val str = """
    {
        "id": 1,
        "name": "小明",
        "address": null
    }
"""

val user = Gson().fromJson(str, User::class.java)
Log.i("MainActivity", "user: $user") // user: User(id=1, name=小明, address=null)
    

序列化(serialization)

將物件轉換為 json
    
    val user2 = User(2, "小红", "Taipei")
    val str2 = Gson().toJson(user2)
    Log.i("MainActivity", "str2: $str2") // str2: {"address":"Taipei","id":2,"name":"小红"}
    

json 屬性名稱和物件屬性名稱不同

上面有提到名稱不同時可以使用 SerializedName 註解標記,使用 SerializedName 也可以達成產生中文 json 格式:
    
data class User(
    @SerializedName("編號") val id: Int,
    @SerializedName("姓名") val name: String,
    @SerializedName("地址") val address: String?
)
    

將物件轉換為中文 json
    
    val user3 = User(3, "小白", "家")
    val str3 = Gson().toJson(user3)
    Log.i("MainActivity", "str3: $str3") // str3: {"地址":"家","編號":3,"姓名":"小白"}
    

忽略屬性

筆者在 javadoc 上查詢到是使用 @Expose,但是不起作用,最後測試出來可以使用 @Transient 註解標記屬性,該屬性在序列化和反序列化就都會被忽略
    
data class User(
    val id: Int,
    val name: String,
    @Transient val address: String?
)
    


參考資料:
GitHub - google/gson
javadoc.io - Package com.google.gson.annotations

留言