Serializable 과 Parcelable 이란?
Android 에서 작업시 Activity 간 이동이나 다른 앱 Compnent 이동시 Intent를 사용함.
이때 데이터 객체 등을 전달하기 위해 Class를 직렬화하는 부분들을 추가하여 사용함.
Serializable 이나 Parcelable을 사용하게 됨.
보통 개발자 편의성이나 유지보수는 Serializable이 우위고, 런타임시 성능은 Parcelable이 낫다고들 해 옴.
참고로 Serializable에서 직렬화 프로세스를 직접 구현하면 성능까지 더 우위라는 포스팅도 있음.
[https://medium.com/@limgyumin/parcelable-vs-serializable-%EC%A0%95%EB%A7%90-serializable%EC%9D%80-%EB%8A%90%EB%A6%B4%EA%B9%8C-bc2b9a7ba810](https://medium.com/@limgyumin/parcelable-vs-serializable-정말-serializable은-느릴까-bc2b9a7ba810)
위 링크의 포스팅에 잘 설명이 되어 있고 특히 아래 내용은 공감되는 부분이었음.
제 개인적 생각에는 0.000042 밀리초 빠르게 앱을 실행하는것에 집중하기 보다는 차라리 내가 만드는 이 앱 이 사용자가 원하는 일을 잘 처리하고 만족할 만한 결과를 내도록 집중하는것이 더 가치가 있는 일이 아닐까 싶습니다.
Kotlin에서 Parcelable 적용
어쨋든 Parcelable을 사용한다고 치고 Kotlin에서 사용시 팁을 정리하겠음.
class User {
val name: String? = null
val email: String? = null
}
위 클래스를 Parcelable을 구현하면 아래와 같음.
import android.os.Parcel
import android.os.Parcelable
class User() : Parcelable {
var name: String? = null
var email: String? = null
constructor(parcel: Parcel) : this() {
parcel.run {
name = readString()
email = readString()
}
}
override fun writeToParcel(dest: Parcel?, flags: Int) {
dest?.run {
writeString(this@User.name)
writeString(this@User.email)
}
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<User> {
override fun createFromParcel(parcel: Parcel): User {
return User(parcel)
}
override fun newArray(size: Int): Array<User?> {
return arrayOfNulls(size)
}
}
}
위에서 보다시피 보일러플레이트 코드가 늘어나며, 향후 유지 보수시에도 수정할 부분들이 추가됨.
다행히 Android Extensions 플러그인에서는 실험실 기능으로 아래와 같이 편의기능을 제공함.
1. 실험실 기능 on (app/build.gradle)
android {
compileSdkVersion 28
defaultConfig {
...
}
androidExtensions {
experimental = true
}
}
2. 클래스에 @Parcelize 와 Parcelable 추가 (User.kt)
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
class User(val name: String? = null, val email: String? = null) : Parcelable
원래 소스와 달라진 부분은?
프로퍼티들을 주생성자에 추가함.
단순히 @Parcelize 와 Parcelable 을 추가하면 주생성자에 선언된 프로퍼티들만 직렬화 처리를 함.
그렇다면 아래와 같이 프로퍼티를 주생성자에 넣지 않는다면?
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
class User() : Parcelable {
val name: String? = null
val email: String? = null
}
컴파일 에러는 발생 안함.
다만 런타임시 제대로 프로퍼티들이 직렬화 처리가 안되어 데이터가 없음.
만약 주생성자에서 선언된 것 외의 프로퍼티를 처리해야 한다면 아래와 같이 추가적으로 처리해줘야 함.
import android.os.Parcel
import android.os.Parcelable
import kotlinx.android.parcel.Parceler
import kotlinx.android.parcel.Parcelize
@Parcelize
class User() : Parcelable {
var name: String? = null
var email: String? = null
constructor(parcel: Parcel): this() {
parcel.run {
name = readString()
email = readString()
}
}
private companion object : Parceler<User> {
override fun User.write(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeString(email)
}
override fun create(parcel: Parcel): User {
return User(parcel)
}
}
}
결국 Android Extensions 플러그인의 기능을 안쓰는 것과 큰 차이는 안나는 듯.
결론
Kotlin에서 Parcelable 사용시 Android Extension 플러그인의 실험실 기능을 사용하면 편해짐.
대신 프로퍼티를 꼭 주생성자에 추가하고 사용하자.
'Android개발 > Kotlin' 카테고리의 다른 글
[Kotlin] 무심코 apply 를 쓰다 생긴 일 (0) | 2021.03.20 |
---|---|
[Kotlin] let, apply, run, with 간단 비교 (0) | 2019.06.14 |
[Kotlin] Try Kotlin Lang 사용해보기 (0) | 2018.02.02 |
[코틀린] 코틀린 스터디 시작합니다. (0) | 2018.01.26 |