인텐트에는 부가 데이터(Extra Data)를 넣어 다른 액티비티로 데이터를 전달할 수 있다.
인텐트 안의 Bundle 객체에 putExtra와 getOOOExtra 메소드로 데이터를 넣거나 뺄 수 있다.
Intent putExtra(String name, String value)
Intent putExtra(String name, int value)
Intent putExtra(String name, boolean value)
String getStringExtra(String name)
int getIntExtra(String name, int defaultValue)
boolean getBooleanExtra(String name, boolean defaultValue)
하지만 전달하는 데이터가 기본 자료형이 아닌 객체(Object) 자료형이라면 Parcelable 인터페이스를 사용해 직렬화해야 한다.
Parcelable 인터페이스를 사용하려면 다음의 두 가지 메소드를 구현해야 한다.
publuc abstract int describeContents()
public abstract void writetoParcel(Parcel dest, int flags)
describeContents() 메소드는 직렬화하려는 객체의 유형을 구분할 때 사용한다. 여기서는 단순히 0을 반환한다.
writetoParcel() 메소드는 객체가 가지고 있는 데이터를 Parcel 객체로 만들어주는 역할을 한다.
Parcel 객체는 readOOO()와 writeOOO() 메소드를 제공하므로 기본 데이터 타입을 넣고 확인할 수 있다.
위의 두 가지 메소드를 모두 구현한 다음에는 CREATOR 상수를 만들어야 한다.
이 상수는 Parcel 객체로부터 데이터를 읽어 들여 객체를 생성하는 역할을 한다.
CREATOR 객체는 상수로 정의되고 반드시 static final로 선언되어야 한다.
Parcelable 인터페이스를 구현한 객체를 만들고 그 객체를 인텐트에 넣어 전달해보는 앱을 만들어보았다.
먼저 Parcelable 자료형으로 된 객체 SimpleData를 구현하였다.
package org.techtown.sampleparcelable;
import android.os.Parcel;
import android.os.Parcelable;
public class SimpleData implements Parcelable {
int number;
String message;
public SimpleData(int num, String msg){
number = num;
message = msg;
}
protected SimpleData(Parcel in) {
number = in.readInt();
message = in.readString();
}
public static final Creator<SimpleData> CREATOR = new Creator<SimpleData>() {
@Override
public SimpleData createFromParcel(Parcel in) {
return new SimpleData(in);
}
@Override
public SimpleData[] newArray(int size) {
return new SimpleData[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(number);
dest.writeString(message);
}
}
SimpleData 객체는 문자열과 정수, 두 개의 변수를 가졌으며, Parcelable 인터페이스를 구현하므로 implements Parcelable 코드가 추가되었다.
SimpleData 객체는 생성자로 Parcel 객체를 파라메터로 받는데, 이 경우에 readInt와 readString 메소드를 이용해 데이터를 읽어 들인다.
protected SimpleData(Parcel in) {
number = in.readInt();
message = in.readString();
}
writetoParcel 메소드는 SimpleData 객체 안에 들어 있는 데이터를 Parcel 객체로 만드는 역할을 한다.
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(number);
dest.writeString(message);
}
그래서 이 메소드 안에는 writeInt와 writeString 메소드가 있다.
CREATOR 객체는 상수로 정의되어 있으며 새로운 객체가 만들어지는 코드가 들어가므로 new SimpleData()와 같이 SimpleData 객체를 만든다.
public static final Creator<SimpleData> CREATOR = new Creator<SimpleData>() {
@Override
public SimpleData createFromParcel(Parcel in) {
return new SimpleData(in);
}
@Override
public SimpleData[] newArray(int size) {
return new SimpleData[size];
}
};
결과적으로 SimpleData 클래스 안에 parcel 객체의 데이터를 읽는 부분과 Parcel 객체로 쓰는 부분을 정의하게 된다.
다음은 MainActivity에서 버튼을 누르면 MenuActivity로 Intent를 통해 데이터를 전달하며 화면을 전달하도록 구현하였다.
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE_MENU = 101;
public static final String KEY_SIMPLE_DATA = "data";
.
.
.
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent= new Intent(getApplicationContext(), MenuActivity.class);
SimpleData data = new SimpleData(100, "Hello World");
intent.putExtra(KEY_SIMPLE_DATA, data);
startActivityForResult(intent, REQUEST_CODE_MENU);
}
});
SimpleData 클래스로 객체를 만들어 putExtra() 메소드를 사용해 SimpleData 객체를 부가 데이터로 추가하였다.
다음으로 MainActivity로부터 Intent를 받아 처리하는 MenuActivity를 구현하였다.
.
.
.
Intent intent = getIntent();
processIntent(intent);
}
private void processIntent(Intent intent){
if(intent != null){
Bundle bundle = intent.getExtras();
SimpleData data = bundle.getParcelable(KEY_SIMPLE_DATA);
if(intent != null){
textView.setText("전달받은 데이터\nNumber : " + data.number + "\nMessage : " + data.message);
}
}
}
}
getIntent() 메소드로 Intent 객체를 반환하여 받고, Intent 객체에 getExtra() 메소드를 통해 Bundle 자료형의 객체를 반환한다.
이렇게 참조한 객체를 getParcelable() 메소드로 객체를 참조해 화면의 텍스트뷰에 보여주도록 하였다.