[개념] Parcelable 란?

쓰리원·2022년 5월 25일
0
post-thumbnail

안드로이드 컴포넌트(Activity 등등)나 Fragment간에 클래스로 데이터를 주고 받을 때 Serializable, Parcelable을 구현해야 합니다.

1. Parcelable 란?

Parcelable은 Java가 아닌 Android SDK의 인터페이스입니다. 이 기법은 Serializable보다 빠르고 Android에서 사용하기를 권장됩니다. Serializable과는 다르게 reflection을 사용하지 않고 직렬화/역직렬화를 하는 과정을 개발자가 모두 구현해주어야 합니다.

그렇게 구현된 코드가 미리 컴파일되어 런타임에 빠르게 처리됩니다. 런타임에 따로 객체를 여러개 생성하지 않으며 GC의 부담은 덜게되니 확실히 Serializable보다 나은 방법입니다. 하지만 이 Parcelable의 단점을 꼽는다면 구현을 위한 보일러플레이트 코드가 늘어난다는 점입니다. 

data class Person(
    var age: Int,
    var name: String,
    val birthday: String
) : Parcelable {

    constructor(parcel: Parcel) : this(
        parcel.readInt(),
        parcel.readString() ?: "",
        parcel.readString() ?: ""
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(age)
        parcel.writeString(name)
        parcel.writeString(birthday)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Person> {
        override fun createFromParcel(parcel: Parcel): Person {
            return Person(parcel)
        }

        override fun newArray(size: Int): Array<Person?> {
            return arrayOfNulls(size)
        }
    }
}

위의 Serializable과는 달리 늘어난 코드를 보실 수 있습니다. 직렬화를 위해 writeToParcel라는 메서드를 통해 Parcel객체에 데이터를 저장하고 역직렬화 할때에 createFromParcel이라는 메서드를 통해 Parcel로부터 데이터를 복원하고 Person객체를 다시 복원하게 됩니다. 이 모든 과정을 개발자가 직접 구현해야 한다는 부담은 있지만 미리 컴파일되어 런타임에 실행되니 reflection보다 확실히 성능상의 이점이 있습니다.

2. @Parcelize 란?

Serializable의 구현하기 쉬운 장점과 Parcelable의 성능상 이점을 모두 가질 수 있습니다. 데이터를 전송하기만 하는 간단한 구현에는 하이브리드 기능을 가진 최종병기인 셈입니다.

kotlin-parcelize 플러그인은 Parcelable 구현을 자동으로 해줍니다.
새로운 클래스를 생성도 필요 없고 @Parcelize 어노테이션을 추가하는 것만으로 직접 Parcelable 관련 코드를 작성 한 것과 같이 동작합니다.

컴파일타임에 바이트 코드 변조를 하기 때문에 추가되는 메서드 및 런타임시 오버헤드 비용도 발생하지 않습니다. 그리고 이 플러그인은 구글과 JetBrains가 협업하여 만든 3rd-party 라이브러리 입니다.

코틀린(1.4.20기준)에서만 사용할 수 있기 때문에 다음과 같은 프로젝트 설정이 되어 있어야 합니다.

build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'

import kotlinx.parcelize

@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable

주요 제약사항은 @Parcelize를 사용하려면 직렬화 된 모든 속성이 기본 생성자(Primary constructor)에 선언되어야 하며, abstract 또는 sealed 클래스를 허용하지 않습니다.

3. Parcelable 적용

4. reference

https://developer.android.com/reference/android/os/Parcelable
https://developer.android.com/kotlin/parcelize
https://kotlinlang.org/docs/serialization.html#example-json-serialization

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글