0. History
- 이 글은 2012-01-25 초안 작성 시작하였습니다.
- 오래된 정보, 잘못된 정보, 오타가 있다면 Comment 남겨주세요. 확인 후 수정하겠습니다.
- 이 글은 2012-01-25 초안 작성 완료하였습니다.
1. Information
Parcelable 이 뭐죠?
Developer 를 참조하여 설명 드리겠습니다.
Parcelable의 뜻은 소포 또는 꾸러미란 뜻입니다. Parcelable 은 꾸러미화 하는 것을 말하겠지요.
왜 이녀석을 "꾸러미화" 라고 했는지 한번 알아보겠습니다.
이 Parcelable 는 Interface 로, 이 녀석을 구현한 class는 Parcel 로 쓰여질 수도 있고, Parcel 로 부터 원래 Object 로 복구될 수도 있습니다. Process 간 정보 교환시 포장 압축하여 전달하고, 받으면 포장을 해제하는 것을 Interface로 만든 것이라 보시면 되겠습니다.
Serializable 과 매우매우 흡사한 녀석입니다.
[Serializable 에 대한 Blog 글]
이 Parcelable 을 구현한 class 는 CREATOR 라는 static filed 를 "반드시" 가지고 있어야 합니다.
이 CREATOR 라는 녀석은 Parcelable.Creator interface 를 구현한 놈으로, 해당 Parcel 이 어떻게 restore 되는지를 기술하고 있습니다.
이 Parcelable 은 IPC ( Inter Process Communication ), 즉 Process 간 통신에 아주 유용하게 쓰이는 Interface 로,
이 녀석을 구현한 class 는 IPC 시 추가 작업 없이 바로 process 사이를 넘어 다닐 수 있습니다. 물론 Serializable에 비해 더 빠르기도 합니다.
그럼 Parcel 이라는 녀석은 뭐하는 녀석이죠?
Parcel 은 꾸러미 그 자체로, IPC 시 이 꾸러미를 다른 프로세스로 휙 던져주는 방식입니다.
Parcelable class 가 IPC 를 위해서 포장, 압축이 된 형태라고 볼 수 있습니다.
택배처럼 꾸러미에 대한 모든 내용은 이미 포장 & 접수 측에서 다 해결했으니,
IPC 단계에서는 해당 Process 로 전달만 하면 되는 것입니다.
포장을 해제하는 것도 물론 고객님 ( 해당 object를 받는 process ) 의 역할이죠.
즉, 중간단계인 IPC 에서는 그저 "배달" 만 해주면 된다는 것입니다.
Developer 를 참조하여 부가 설명을 하자면..
Parcel은 IBinder 를 통해 전달 될 수 있는 Data 나 Object Reference의 Container 입니다.
이 Parcel 은 primitive type, primitive array type 또는 Parcelable class 들을 가지고 있을 수 있습니다.
이 Parcel 은 Serialization과는 "맥락"은 비슷하지만 "매카니즘"은 다릅니다.
이 Parcelable은 IPC 에서 high performance를 낼 수 있는 형태로 되어 있습니다.
[Parcel 에 대한 구체적 이야기]
어떻게 만들죠?
1. 먼저 Parcelable 하지 않은 class에 Parcelable implements 를 더해줍니다.
2. 기본적으로
public int describeContents() 와 public void writeToParcel( Parcel dest, int flags ) 를 구현해 주어야 합니다.
describeContents() 는 Parcel 의 내용을 기술해주는 녀석인데, 실생활(?) 에서 잘 쓰이지 않습니다.
보통 return 0; 을 해줍니다.
writeToParcel( Parcel dest, int flags ) 는 Parcel 즉 상자 안에 내용물을 넣는 작업을 해줍니다.
이 때 주의해야 할 것은 쓰는 순서입니다. Parcel 을 unmarshalling 할 때 쓴 순서대로 읽어와야 하기 때문입니다.
3. Developer 에 기술된데로, static 으로 정의된 CREATOR field가 필요합니다.
이 CREATOR 는 Parcelable.Creator<T> type 으로 생성되며, 선언과 동시에 초기화 ( Initialize ) 되어야 합니다.
T 는 generic type 으로 Parcelable을 구현하는 class 를 넣어주면 됩니다.
이 CREATOR 라는 녀석은 unmarshalling 을 할 때 Parcelable class 를 생성해주는 역할을 합니다.
기본적으로 public T createFromParcel( Parcel source ) 와 public T[] newArray( int size ) 를 구현해주어야 합니다.
createFromParcel( Parcel source ) 는 Parcel이 된 Parcelable class 를 restore 하는 작업을 써주게 됩니다.
여기서 값을 read하는 순서는 위의 writeToParcel에서 write 한 순서와 동일하게 해야 합니다.
마지막으로 restore 된 class 를 return 해주어야 하죠.
newArray( int size )는 Parcel.createTypeArray() 함수를 호출했을 때 불리며,
해당 parcelable로 구성된 array를 return하기 때문에
return new T[size]; 면 보통 충분합니다.
이렇게 Parcelable class 만드는 작업이 끝났습니다.
예제를 보여주세요
가장 많이 예제로 제시되는 Rect class parcelable 로 만들기 입니다.
<Original>
public class Rect{
public int left;
public int right;
public int top;
public int bottom;
}
<Parcelable implemet>
public class Rect implements Parcelable{
public int left;
public int right;
public int top;
public int bottom;
public int describeContents(){
return 0;
}
// 쓰는 순서 주의
public void writeToParcel( Parcel dest, int flags ){
dest.writeInt( left );
dest.writeInt( write );
dest.writeInt( top );
dest.writeInt( bottom );
}
// 반드시 필요한, static filed 로 정의된 CREATOR object.
public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>(){
// 읽는 순서에 주의
public Rect createFromParcel( Parcel source ){
Rect r = new Rect();
r.left = source.readInt();
r.right = source.readInt();
r.top = source.readInt();
r.bottom = source.readInt();
return r;
}
public Rect[] newArray( int size ){
return new Rect[size];
}
}
}
2. Summary
- Parcelable 은 IPC ( 프로세스 간 통신 ) 시 오브젝트는 Parcel 의 형태로 만들기 위한, 그리고 원래 class 형태로 복구되기 위한 과정을 기술하도록 하는 Interface 입니다.
- Parcel 은 소포처럼 포장이 되어 있어, IPC 시 운반만 하면 되도록 포장과 포장해제에 대한 준비가 마쳐진 Object 입니다. Parcelable class 가 IPC 시 marshalling( 마샬링 )을 통해 Parcel 의 형태로 변하고, 수신이 완료되면 unmarshalling( 언마샬링 ) 을 통해 원래의 object 로 돌아갑니다.
- Parcelable 은 static filed 로 CREATOR 를 반드시 가지고 있어야 하며, 선언과 동시에 초기화가 됩니다. 이 CREATOR 는 기본적으로 createFromParcel() 과 newArray() 를 구현해주어야 하는데, createFromParce()은 unmarshalling 과정을 기술해 줍니다.
- Parcelable interface는 기본적으로 describeContents() 와 writeToParcel() 을 기술해주어야 하며, writeToParcel 은 marshalling 과정을 기술합니다.
- Marshalling & Unmarshalling 시 쓰고 읽는 순서는 동일해야 합니다. ( Queue 의 개념 )
3. References
- http://developer.android.com/reference/android/os/Parcel.html
Android Developer Doc. Parcel.
- http://developer.android.com/reference/android/os/Parcelable.html
Android Developer Doc. Parcelable.
4. Tag
댓글