Serializable vs Parcelable

jeunguri·2022년 3월 30일
0

android

목록 보기
1/13

안드로이드에서는 프로세스 통신을 위해 Bundle 클래스를 사용한다. Bundle 클래스는 Key와 Value가 있는 Map형태의 클래스다. 하지만 Bundle에서 많은 데이터가 들어가 있는 자바의 POJO나 코틀린의 data class의 경우 Value로 입력하기 어렵다. 따라서 Serializable이나 Parcelable한 객체로 만들어 intent 를 통해 액티비티간 데이터를 전달할 수 있다.



Serializable

Serializable는 표준 JAVA 인터페이스로 자바 시스템 내부에서 사용하는 객체를 외부의 자바 시스템에서도 사용할 수 있도록 바이트 형태로 데이터를 변환시켜주는 기술이다.
안드로이드 상에서 Serializable를 이용해 액티비티간 또는 서비스간 클래스 타입의 데이터를 주고 받는 용도로 사용한다.

data class Person(
	val name: String, 
    val age: Int
    ): Serializable 

val intent = Intent().apply { 
	this.putExtra("person", Person("gildong", 20)) } 
startActivity(intent)

Person 클래스를 Serializable 선언해주면 다른 액티비티에 클래스 형태 그대로 전달해줄 수 있다.

하지만 Serializable는 내부적으로 자바의 reflection이 발생하게 되고, 바이트 형태로 변환된 데이터를 다시 객체의 형태로 변환시키면서 JVM 내부에 임시 객체를 많이 생성하게 되고 이 과정에서 garbage가 발생하게 되어 앱의 성능 저하 및 배터리 소모가 일어난다.



Parcelable

Parcelable은 안드로이드 SDK를 포함하고 있는 인터페이스로 reflection 방법을 사용하지 않고 사용자가 직렬화 방법을 직접 작성한다. Serializable과 달리 구현해야 할 필수 메서드들이 존재한다.

data class Person() : Parcelable{

    constructor(parcel: Parcel) : this() {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
    }

    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)
        }
    }

}

직렬화를 위해 writeToParcel 메서드를 통해 Parcel 객체에 데이터를 저장하고, 비직렬화 할 때는 createFromParcel 메서드를 통해 Parcel로부터 데이터를 복원하고 Person객체를 다시 복원하게 된다.

그러나 이렇게 되면 Parcelable은 구현을 위한 보일러플레이트 코드가 늘어나게 된다. 따라서 Kotlin-android-extension 플러그인을 사용하면 @Parcelize 를 사용하여 아래와 같이 간단하게 코드 구현이 가능하다.

@Parcelize 
data class Student(val name: String?, val age: Int) : Parcelable {}


0개의 댓글