Parcelable vs Serializable

종종 앱을 개발하다보면 액티비티와 같은 안드로이드 컴포넌트에 POJO같은 데이터를 전달해야 할 일이 있습니다. 액티비티 객체는 우리가 만들지 않고 안드로이드 시스템에서 관리하고 있으므로 컴포넌트로 데이터를 전달하기 위해서는 반드시 인텐트를 통해서 전달하게 됩니다. 예) putExtra(Parcelable) 또는 putExtra(Parcelable)

Serializable

Serial(직렬의) + ~able(~가능한)
Serializable(시리어라이저블)은 자바 표준 인터페이스 중 하나로 안드로이드 SDK에 포함되어있지 않습니다. 어쨌거나 전달하고자 하는 데이터 클래스(POJO)에 Serializable인터페이스를 구현만 하면 액티비티로 데이터를 전달할 준비가 완료 됩니다. 예제를 한번 보시죠.

import java.io.Serializable;

public class Person implements Serializable {

    private String name;
    private int age;


    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

아주 간단하게 implements Serializable 을 추가 하는것으로 Person객체를 다른 액티비티에 전달할 준비가 완료 되었습니다.

간단하게 구현만큼 그에 따른 댓가를 치르게 됩니다. 내부적으로는 자바의 리플렉션의 발생하게 되고 이로 인해 많은 오브젝트 생성과 그에 따른 Garbage Collection이 발생하게되어 안드로이드 앱의 성능을 낮추고 베터리를 더 잡아 먹게 됩니다.

Parcelable

Parcel(소포, 택배) + ~able(~가능한)
Parcelable(파슬러블)은 또 다른 인터페이스의 한종류로 자바가 아닌 안드로이드 SDK내에 포함되어있습니다. Parcelable은 리플렉션을 사용하지 않기위해 특별하게 설계되었습니다. 우선 예제를 한번 확인해보도록하겠습니다.

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {

    private String name;
    private int age;


    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

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

    protected Person(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
    }

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

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

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

옛날 기기 대상 지표긴 하지만 여전히 비슷하게 적용됩니다. 압도적으로 Parcelable인터페이스가 데이터를 전달할때 적은 시간을 소요하는것을 확인할 수 있습니다.

Why is it so FAST?

Parcelable은 IPC(프로세스간 통신)를 이용하기 때문입니다. 프로세스들 사이에서 서로 데이터를 주고 받는것을 IPC라고 하는데요. 프로세스간의 메모리 영역을 공유 할 수 없기에 Parcelable인터페이스는 커널메모리를 통해 데이터를 다른 프로세스로 전달하는 통로를 만들어 줍니다.

Parcelable을 쉽게 구현하기

안드로이드 스튜디오(InjelliJ IDE)의 플러그인을 활용하면 쉽게 보일러플레이트 코드를 생성할 수 있습니다.

  1. 설정-플러그인을 클릭하여 위와 같은 화면을 띄웁니다.
  2. 하단중앙의 Browse repositories…을 클릭합니다.
  3. 키워드 Parcelable을 입력하여 스크린샷과 같이 첫번째 플러그인을 선택하여 우측의 install(녹색버튼)을 누릅니다.
  4. 설치가 끝났다면 안드로이드 스튜디오를 재시작 합니다.
  5. 데이터클래스(POJO)로 가서 Code-generate…를 클릭합니다. Mac 단축키 기준 cmd+n을 눌러도 됩니다.
  6. Parcelable항목이 추가된것을 확인할 수 있습니다. 클릭하면 코드가 생성됩니다.

Conclusion

Serializable은 분명히 개발자 입장에서는 편합니다. 인터페이스 구현만 하면되니까요. 하지만 앱 사용자에게는 퍼포먼스저하와 베터리 드래인이라는 큰 단점을 안겨 줍니다. 조금은 귀찮더라도 Serializable은 지양하고 Parcelable을 사용하는 것이 바람직 합니다.

Buy me a coffeeBuy me a coffee
카테고리: Android

0개의 댓글

답글 남기기

이메일은 공개되지 않습니다.