[Android] Kotlinx Serialization
Serialization 이란?
- 데이터 구조나 오브젝트 상태를 동일하거나 다른 컴퓨터 환경에 저장하고 나중에 재구성할 수 있는 포맷으로 변환하는 과정.
자바에서 정의하는 Serialization 이란 ?
- 자바 언어에서 사용되는 Object 또는 Data를 다른 컴퓨터의 자바 시스템에서도 사용 할 수 있도록 바이트 스트림 형태로 변환하는 포맷 변환 기술을 말한다.
- 반대 개념인 역직렬화(Deserialization)는 바이트 스트림으로 변환된 데이터를 자바 시스템의 Object 또는 Data로 변환하는 기술이다.
너무 깊이 가지 말고 간단하게 정리하자면...
Android 에서는 컴포넌트간의 Bundle을 통한 데이터 전달이나 서버통신을 할 때 필수적으로 하는 것이 데이터의 직렬화/역직렬화다.
보통 Java Interface인 Serializable과 Android SDK Interface인 Parcelable을 비교하게 되는데 다음과 같은 내용을 많이 찾아 볼 수 있다.
- Serializable : 사용 시 Reflection 발생에 따라 많은 객체가 생성되고 해제되면서 GC가 발생하고 많은 비용이 발생하게 된다.
- Parcelable : 내부에 Boiler plate code가 생성되기 때문에 유지보수에 비용이 든다. 성능면에서는 Serializable 보다 좋다.
문제점으로는 서버에서 응답 값을 받아 올 때 data class로 받게 되는데 위의 두가지를 사용하면 값이 없을 경우 default value를 무시하고 0 or null 값으로 직렬화되는 것을 볼 수 있다.
이런 경우에 Kotlin project를 위한 JSON serialization인 Kotlinx Serialization 을 사용하게 되면 위의 문제점을 해결 할 수 있다.
다음과 같이 Serializable 어노테이션을 달아주면 쉽게 사용할 수 있다.
@Serializable data class Data(val a: Int, val b: String) |
Gson 과 Json 을 통해 json 텍스트를 각각 클래스로 변환하면 다음과 같다.
enum class Status { SUPPORTED }
@Serializable
data class JsonData(
val a: Int,
val b: String,
val c: Status = Status.SUPPORTED
)
data class GsonData(
val a: Int,
val b: String,
val c: Status = Status.SUPPORTED
)
fun main() {
val jsonText: String = ... /* json string from assets/xxx.json */
val gsonData = Gson().fromJson<GsonData>(jsonText, object : TypeToken<GsonData>() {}.type)
val jsonData = Json.decodeFromString<JsonData>(jsonText)
...
}
다음과 같은 결과를 볼 수 있다.
@Serializable 어노테이션을 통해 Json으로 파싱하게 되면 다음과 같이 default value가 들어가게 되고
{"a":1,"b":"test","c":":"SUPPORTED"}
@Serializable 어노테이션이 없는 data class로 Gson으로 파싱하게 되면 다음과 같이 null 이 들어가는 것을 볼 수 있다.
{"a":1,"b":"test","c":":null}
장점은 다음과 같다.
- @Serializable 을 빼놓을 경우 컴파일 에러가 발생한다.
- default value가 적용되어 파싱 에러에 대한 처리가 줄고 사용성이 좋아진다.
- Reflection을 사용하지 않고 구현되었다.