본문 바로가기
개발/Android

[Android] Parcelable과 Serializable의 차이점

by blacktree 2023. 3. 7.
반응형

 

안드로이드에서 데이터를 전달하는 방법은 크게 Parcelable과 Serializable 두 가지가 있습니다.

이 두 가지 방법은 객체를 직렬화하여 전송하는 방법이지만, 각각의 방법은 내부적으로 다른 방식으로 동작합니다.

이번 블로그에서는 Parcelable과 Serializable의 차이점에 대해 자세히 알아보겠습니다.

 

목차

  1. Parcelable과 Serializable 개념 이해하기
  2. Parcelable과 Serializable의 차이점
  3. Parcelable 사용 방법
  4. Serializable 사용 방법
  5. Parcelable과 Serializable 사용 시 고려사항
  6. 결론

 

1. Parcelable과 Serializable 개념 이해하기

  • Parcelable
    • Parcelable은 안드로이드에서 제공하는 인터페이스로, 객체를 전달하기 위해 사용됩니다.
    • Parcelable을 사용하면 객체를 직렬화하여 안드로이드 OS에서 처리할 수 있는 바이트 배열로 변환하여 전달할 수 있습니다.
    • Parcelable 인터페이스를 구현한 객체는 안드로이드 OS에서 Intent나 Bundle에 담아 전달할 수 있습니다.
  • Serializable
    • Serializable은 Java에서 제공하는 인터페이스로, 객체를 직렬화하여 전달하기 위해 사용됩니다.
    • Serializable을 사용하면 객체를 바이트 스트림으로 변환하여 전달할 수 있습니다.
    • Serializable 인터페이스를 구현한 객체는 Java에서 제공하는 ObjectOutputStream을 사용하여 전달할 수 있습니다.

 

2. Parcelable과 Serializable의 차이점

Parcelable과 Serializable은 객체를 직렬화하여 전달하기 위한 방법이지만, 내부적으로 다음과 같은 차이점이 있습니다.

  • 속도
    • Parcelable은 Java의 Serializable보다 빠릅니다.
    • Parcelable은 안드로이드 OS에서 직접 처리하기 때문에 직렬화와 역직렬화 시간이 적습니다.
    • Serializable은 Java의 Reflection을 사용하기 때문에 직렬화와 역직렬화 시간이 상대적으로 느립니다.
  • 크기
    • Parcelable은 Java의 Serializable보다 객체를 직렬화할 때 생성되는 데이터 크기가 작습니다.
    • Parcelable은 객체의 멤버 변수들을 Parcel에 쓰기 때문에 필요한 데이터만 쓰게 됩니다.
    • Serializable은 객체의 모든 데이터를 직렬화하기 때문에 불필요한 데이터까지 모두 쓰게 됩니다.
  • 안정성
    • Parcelable은 Java의 Serializable보다 안정성이 높습니다.
    • Parcelable은 직렬화와 역직렬화에 대한 오류 검사를 수행하기 때문입니다.

 

3. Parcelable 사용 방법

Parcelable을 사용하려면 다음과 같은 단계를 거쳐야 합니다.

3.1. Parcelable 인터페이스를 구현합니다.

public class MyObject implements Parcelable {
    private int id;
    private String name;

    public MyObject(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // Parcelable 인터페이스의 메서드 구현
    @Override
    public int describeContents() {
        return 0;
    }

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

    // Parcelable.Creator 구현
    public static final Creator<MyObject> CREATOR = new Creator<MyObject>() {
        @Override
        public MyObject createFromParcel(Parcel in) {
            return new MyObject(in.readInt(), in.readString());
        }

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

3.2. 객체를 전달할 때는 Intent나 Bundle을 사용합니다.

MyObject myObject = new MyObject(1, "Hello");

Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("my_object", myObject);
startActivity(intent);

3.3. 전달받은 객체를 사용할 때는 Parcelable.Creator의 createFromParcel() 메서드를 사용합니다.

Intent intent = getIntent();
MyObject myObject = intent.getParcelableExtra("my_object");

Toast.makeText(this, myObject.getName(), Toast.LENGTH_SHORT).show();

 

4. Serializable 사용 방법

4.1. Serializable을 사용하려면 Serializable 인터페이스를 구현해야 합니다.

public class MyObject implements Serializable {
    private int id;
    private String name;

    public MyObject(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter and Setter
    ...
}

4.2. Serializable을 사용하여 객체를 전달할 때는 ObjectOutputStream을 사용합니다.

MyObject myObject = new MyObject(1, "Hello");

try {
    FileOutputStream fileOut = new FileOutputStream("myobject.ser");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(myObject);
    out.close();
    fileOut.close();
} catch (IOException e) {
    e.printStackTrace();
}

4.3. Serializable을 사용하여 전달받은 객체를 사용할 때는 ObjectInputStream을 사용합니다.

MyObject myObject = null;

try {
    FileInputStream fileIn = new FileInputStream("myobject.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    myObject = (MyObject) in.readObject();
    in.close();
    fileIn.close();
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}

Toast.makeText(this, myObject.getName(), Toast.LENGTH_SHORT).show();

 

5. Parcelable과 Serializable 사용 시 고려사항

  1. Parcelable
    1. Parcel 크기 제한
      1. Parcelable을 사용할 때는 Parcel의 크기가 1MB를 넘을 수 없습니다.
      2. 큰 객체를 전달할 때는 분할해서 전달하는 방법을 고려해야 합니다.
    2. 안드로이드 OS에서만 사용 가능
      1. Parcelable은 안드로이드 OS에서만 사용할 수 있습니다.
      2. 따라서 Parcelable을 사용하여 전달한 객체는 안드로이드 애플리케이션에서만 사용할 수 있습니다.
  2. Serializable
    1. Serializable 인터페이스 구현
      1. Serializable을 사용하는 클래스는 Serializable 인터페이스를 구현해야 합니다.
      2. Serializable 인터페이스를 구현하지 않은 클래스는 객체 직렬화를 할 수 없습니다.
    2. transient 키워드 사용
      1. Serializable을 사용할 때는 transient 키워드로 선언된 필드는 직렬화되지 않습니다.
      2. transient 키워드로 선언된 필드는 객체의 상태를 나타내는 것이 아니므로 직렬화할 필요가 없습니다.
    3. 객체 버전 관리
      1. Serializable을 사용하여 객체를 전달할 때는 객체 버전 관리를 고려해야 합니다.
      2. 객체의 클래스나 멤버 변수를 변경하면 이전 버전과 호환되지 않을 수 있습니다.
      3. 객체 버전 관리를 위해 serialVersionUID 필드를 명시적으로 선언할 수 있습니다.

 

6. 결론

Parcelable과 Serializable의 성능을 비교하면 Parcelable이 더 빠르다는 것이 일반적인 경향입니다.

Parcelable은 Parcel에 직접 쓰고 읽기 때문에 객체를 직렬화하는 시간이 짧습니다.

Serializable은 ObjectOutputStream과 ObjectInputStream을 사용하기 때문에 객체를 직렬화하는 시간이 더 길어집니다.

하지만 Parcelable이 더 빠르다고 해서 항상 Parcelable을 사용해야 하는 것은 아닙니다.

객체의 크기와 전달 방식에 따라서는 Serializable을 사용하는 것이 더 나은 경우도 있습니다.

따라서 Parcelable과 Serializable 중 어떤 것을 사용할지는 상황에 따라 결정해야 합니다.

객체 크기가 작고 안드로이드 OS에서만 사용하는 경우 Parcelable을, 객체 크기가 크거나 다른 플랫폼과도 호환해야 하는 경우 Serializable을 사용하는 것이 좋습니다.

 

 

참고 자료

 

Parcelable  |  Android Developers

 

developer.android.com

 

 

Serializable (Java SE 11 & JDK 11 )

 

docs.oracle.com

 

728x90
반응형

댓글