Android

[Android] Serializable, Parcelable

Sangyoon98 2023. 7. 2. 11:51

안드로이드에서 액티비티와 같은 안드로이드 컴포넌트에 POJO 같은 데이터를 전달을 해야 할 때가 있다.

액티비티와 같은 안드로이드 컴포넌트들에 데이터를 전달하기 위해서는 반드시 인텐트를 통해 전달하게 된다.

이 때 데이터 객체를 전달할 수 있도록 직렬화 인터페이스로 Serializable과 Parceable을 제공한다.

 

Serializable

자바 표준 인터페이스 중 하나로 안드로이드 SDK에 포함되어 있지 않다.

전달하고자 하는 데이터 클래스(POJO)에 Serializable 인터페이스를 구현만 하면 액티비티로 데이터를 전달할 준비가 된다.

 

Java

더보기
import java.io.Serializable;

public class CommunityListResponse implements Serializable {

    private String USR_NM;
    private int COM_ID;

    public CommunityListResponse(
        String USR_NM,
        int COM_ID
    ) {
        this.USR_NM = USR_NM;
        this.COM_ID = COM_ID;
    }

    public String getUSR_NM() {
        return USR_NM;
    }
    
    public void setUSR_NM(String USR_NM) {
        this.USR_NM = USR_NM;
    }

    public int getCOM_ID() {
        return COM_ID;
    }

    public void setCOM_ID(int COM_ID) {
        this.COM_ID = COM_ID;
    }
}

Kotlin

data class CommunityListResponseData(
    val USR_NM: String,
    val COM_ID: Int
) : Serializable

아주 간단하게 Serializable을 Implements로 추가하면 된다.

 

간단하게 구현하는 만큼 그에 따른 댓가를 치르게 된다. 내부적으로 자바의 리플렉션이 발생하게 된다.

이로 인해 많은 오브젝트 생성과 그에 따른 Garbage Collection이 발생하게 되어 안드로이드 앱의 성능을 낮추고 배터리를 더 잡아먹게 된다.

 

안드로이드와 Java의 Reflection | 찰스의 안드로이드

Reflection이란? Reflection은 자바 언어의 기능중 하나로 프로그램 내부 속성을 조작 할 수 있게 합니다. 예를 들어 Java클래스가 가지고 있는 모든 멤버의 이름을 가져와서 표시 할 수 있습니다. 다른

www.charlezz.com

 

Parcelable

안드로이드 SDK에 포함된 직렬화 인터페이스

Parcelable은 자바의 리플렉션을 사용하지 않기 위해 특별하게 설계되었다.

 

Java

더보기
import android.os.Parcel;
import android.os.Parcelable;

public class CommunityListResponse implements Parcelable {

    private String USR_NM;
    private int COM_ID;


    public CommunityListResponse(String USR_NM, int COM_ID) {
        this.USR_NM = USR_NM;
        this.COM_ID = COM_ID;
    }

    public String getUSR_NM() {
        return USR_NM;
    }
    
    public void setUSR_NM(String USR_NM) {
        this.USR_NM = USR_NM;
    }

    public int getCOM_ID() {
        return COM_ID;
    }

    public void setCOM_ID(int COM_ID) {
        this.COM_ID = COM_ID;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.USR_NM);
        dest.writeInt(this.COM_ID);
    }

    protected CommunityListResponse(Parcel in) {
        this.USR_NM = in.readString();
        this.COM_ID = in.readInt();
    }

    public static final Parcelable.Creator<CommunityListResponse> CREATOR = new Parcelable.Creator<CommunityListResponse>() {
        @Override
        public Person createFromParcel(Parcel source) {
            return new CommunityListResponse(source);
        }

        @Override
        public CommunityListResponse[] newArray(int size) {
            return new CommunityListResponse[size];
        }
    };
}

Kotlin

data class CommunityListResponseData(
    val USR_NM: String?,
    val COM_ID: Int
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.readInt()
    ) {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(USR_NM)
        parcel.writeInt(COM_ID)
    }

    override fun describeContents(): Int {
        return 0
    }

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

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

리플렉션을 없애기 위해 보일러플레이트 코드가 생겼지만 퍼포먼스는 향상된다.

옛날 기기 지표이긴 하지만 지금도 동일하게 적용된다. 압도적으로 Parcelable 인터페이스가 데이터를 전달할때 적은 시간을 소요한다.

 

두 방식 모두 프로세스들 사이에서 통신하는 방식이지만, Serializable은 JVM 상에서 리플렉션 API를 사용한다. 이는 자바 객체 멤버 및 동작을 식별하지만 불필요한 객체(Garbage Objects)도 많이 생성하게 되는데, 이로 인해 Serialzble이 Parcelable보다 느리다.

 

물론 Serializable 방식에서도 Parcelable처럼 writeObject()와 readObject()를 구현하면 Parcelable보다 빠르다는 의견도 있다고 한다.

 

Parcelable vs Serializable , 정말 Serializable은 느릴까?

원문 : “Parcelable vs Serializable”

medium.com

 

Parcelable이 성능이 빠르지만 보일러플레이트 코드를 작성해야 하는 번거로움이 있다.

물론 요즘 안드로이드 스튜디오에서는 자동으로 코드를 생성해주지만 더욱 쉽게 Parcelable을 사용하는 방법을 제공한다.

코틀린에서는 @Parcelize를 사용하면 간단하게 Parcelable을 구현할 수 있다.

@Parcelize
data class CommunityListResponseData(
    val USR_NM: String,
    val COM_ID: Int
) : Parcelable

 

Parcelable이 성능이 좋고 단점도 적은만큼 Serializable을 지양하고 Parcelable을 사용하는 것이 바람직하다고 한다.