제임스딘딘의
Tech & Life

개발자의 기록 노트/Android

[안드로이드] 서로다른 Activity 사이에 Parcelable사용하여 데이터/객체 전달 및 받는 방법

제임스-딘딘 2010. 12. 30. 13:49

서로다른 액티비티(Activity) 사이에 Parcelable사용하여 데이터/객체 전달 및 받는 방법


Parcelable의 정석적인 사용방법은 아니지만, 객체의 포인터를 액티비티간 주고 받는 방식으로 보면 될 것 같다.

물론 자바는 포인터가 없지만 여기서 사용한 방법은 개념상 포인터를 넘기는것과 같다고 봐도 무방할것 같다.


이미 잘 알려진것과 같이, 안드로이드에서는 서로다른 엑티비티 사이에서 객체를 주고 받기 위해서는 Intent를 이용한다.

그런데 기본 데이터 형인 int, String, short, float... 등이 아니라 사용자 정의 Class의 instance를 넘겨야 하는 상황이라고 생각해보자.

어떻게 해야할까?

이때 사용되는 interface가 Parcelable 이다.

기본 자료형 int, boolean, long, String 등등 이 아닌 일반 Class의 instance를 엑티비티간에 주고 받기 위해서는, Parcelable을 이용해서 포장한 후에 넘겨주어야 한다.


보내는 엑티비티를 A라고 하고, 받는 엑티비티를 B라 가정해보자.

A에서는 Intent에 putExtra( ) 메서드로 객체를 넣고, B에서는 getParcelable( ) 메서드로 객체를 받는다.

이때 사용할 putExtra( )는 아래의 API이다.


Intent putExtra (String name, Parcelable[] value)

Add extended data to the intent. The name must include a package prefix, for example the app com.android.contacts would use names like "com.android.contacts.ShowAll".


name : String, 패키지 접두어를 가진 추가 데이터의 이름.

value : Parcelable, Parcelable[ ] 배열 데이터 값


Cursor의 instance를 넘기는 예제를 보자.

우선 아래와 같이 'Parcelable' interface를 구현하는 'ParcelableCursor' 라는 이름의 Class를 하나 정의한다.

public class ParcelableCursor implements Parcelable {
	static private Cursor mCursor = null;
	static ParcelableCursor obj = null;

	ParcelableCursor(Cursor cursor) {
		mCursor = cursor;
		obj = this;
	}

	public Cursor getCurosr() {
		return mCursor;
	}

	public int describeContents() {
		return 0;
	}
	public void writeToParcel(Parcel out, int flags) {
		;
	}
	public static final Parcelable.Creator CREATOR
	= new Parcelable.Creator() {
		public ParcelableCursor createFromParcel(Parcel in) {
			return obj;
		}
		public ParcelableCursor[] newArray(int size) {
			return new ParcelableCursor[size];
		}
	};     
}


Parcelable interface는 public abstract 메서드가 2개다.

  • abstract int describeContent( )
  • abstract void writeToParcel(Parcel dest, int flags)

그렇지만, 예제코드에서 이 둘은 하는 일이 없다.

받는 엑티비티(B) 쪽에서  Parcelable객체를 전달받고, 해당 객체로부터 Cursor객체를 받기 위해 getCurosr( ) 라는 메서드를 만들어 주었다.


CREATOR 에서만 obj 를 리턴 하는데, 이는 최초 객체가 생성될때 생성자에서 자기 자신을 담고 있는다.

A에서 Cursor객체를 생성해서 putExtra 로 전달하면, B에서는 getParcelable 를 호출할 것이고, 이때  CREATOR가 호출되면서 이는 곧 다른 엑티비티에서 보내온 객체를 할당 받게 된다.


A(보내는 엑티비티) 

ParcelableCursor pc = new ParcelableCursor(cursor);
         intent.putExtra("cursor_instacne", pc);
         startActivity(intent);



B(받는 액티비티)

ParcelableCursor parcelcursor = bundle.getParcelable("cursor_instance");
         Cursor cursor = parcelcursor.getCurosr();


엑티비티 사이 에서 객체를 주고 받는 것은 interface를 맞춰주고 Parcelable객체도 만들어 주어야 하는 약간 손이 가는 작업이다. 객체의 전달은 서로 다른 프로세스 사이에서도 발생할 수 있기 때문에, 속도저하 문제 등에도 어느정도 영향을 줄 수 있다.

때때로, 이렇게 Parcelable을 전달하는게 유용할 경우도 있는데, 예를 들면, 주변 bluetooth device 스캐닝 후의 결과 목록을 위와 같이 Parcelable interface를 통해 UI화면으로 전달하는 것 등이다.

가능하다면 구현 전 설계 단계에서 이런 불필요하고 복잡한 일은 회피 할수 있도록 하는게 바람직 할 것 같다. 또한, 불가피 하게 적용해야 하는 상황이라면, 이 방법을 한번 검토 해보길 바란다.