[210618] 안드로이드 Parcelable 로 데이터 전달하기
액티비티에서 다른 액티비티로 데이터를 전달해야하는 경우가 상당히 자주 있다.
이렇게 데이터를 다른 액티비티로 전달할 때에는 '인텐트(Intent)'에 '부가 데이터(Extra Data)'를 넣어서 전달할 수 있는데
어떻게 데이터를 주고 받을까?
인텐트 안에는 '번들(Bundle)' 객체가 들어 있는데, 이것은 해시테이블과 비슷해서 putExtra()로 데이터를 넣고
getOOOExtra()로 데이터를 가져오는 방식으로 데이터를 주고 받을 수 있다.
데이터를 전달하는 방식 중에 아예 객체 자체를 전달하는 방법도 있는데, 그것은 바로 'Parcelable' 인터페이스를 이용하는 것이다. Parcelable 인터페이스는 Serializable 인터페이스와 비슷하지만 Serialization 했을 때 크기가 작아서
안드로이드 내부의 데이터 전달에 자주 사용된다. 이렇게 Parcelable 인터페이스를 사용하면 객체 자체를 번들에
넣어서 데이터를 전달할 수 있게된다.
Parcelable를 사용하려면 두 개의 메소드를 상속해야하는데,
첫 번째는 describeContents() 메소드이다. 이것은 Serialization 하려는 객체의 유형을 구분할 때 사용된다.
두 번째는 writeToParcel() 메소드이다. 이것은 객체가 가지고 있는 데이터를 Parcel 객체로 만들어준다.
그리고 Parcel 객체는 번들 객체의 putExtra()나 getOOOExtra() 메소드처럼 readOOO(), writeOOO() 메소드로 데이터를 읽고 쓸 수 있다.
Parcelable를 이해하기 위한 예제를 해보겠다. 제목과 내용을 입력한 다음에 버튼을 누르면 액티비티 화면이 전환이
되면서 입력했던 데이터들이 전달되어 TextView에 출력하는 간단한 앱이다.
먼저, Parcelable 인터페이스부터 만들어보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public class ExampleData implements Parcelable { // Parcelable 인터페이스를 상속
String title;
String contents;
public ExampleData(String tit, String content) {
title = tit;
contents = content;
}
public ExampleData(Parcel src) { // Parcel 객체에서 읽기
// 데이터를 읽어서 변수에 할당
title = src.readString();
contents = src.readString();
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { // Parcel 객체로부터 데이터를 읽어서 객체 생성
@Override
public ExampleData createFromParcel(Parcel src) {
return new ExampleData(src); // ExampleData 생성자 호출 후 Parcel 객체에서 읽기
}
// 여기에서 Parcel은 객체 안에 있는 데이터를 다른 곳에 전달할 때 사용된다.
@Override
public ExampleData[] newArray(int size) {
return new ExampleData[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) { // Parcel 객체로 쓰기(객체가 가지고 있는 데이터를 Parcel 객체로 만듬)
dest.writeString(title);
dest.writeString(contents);
}
} // 즉, Parcel 객체의 데이터를 읽는 부분과 쓰는 부분을 정의하는 것임
|
cs |
Parcelable 인터페이스를 만들었으면 데이터를 서로 주고 받을 MainActivity와 ReceiveActivity를 만들어보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE = 101;
public static final String EXAMPLE_DAT_KEY = "data"; // 번들 객체에 데이터를 저장하기 위한 Key
EditText titleEdt, contentEdt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
titleEdt = (EditText)findViewById(R.id.titleEdt);
contentEdt = (EditText)findViewById(R.id.contentEdt);
Button sendBtn = (Button)findViewById(R.id.sendBtn);
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 입력한 제목과 내용의 문자열을 변수에 할당
String title = titleEdt.getText().toString();
String contents = contentEdt.getText().toString();
// 인텐트에 데이터를 넣어서 다른 액티비티로 전달함
Intent intent = new Intent(getApplicationContext(), ReceiveActivity.class);
ExampleData exampleData = new ExampleData(title, contents);
intent.putExtra(EXAMPLE_DAT_KEY, exampleData);
startActivityForResult(intent, REQUEST_CODE);
}
});
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public class ReceiveActivity extends AppCompatActivity {
public static final String EXAMPLE_DATA_KEY = "data"; // 번들 객체에 데이터를 저장하기 위한 Key
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receive);
tv = (TextView)findViewById(R.id.tv);
Button backBtn = (Button)findViewById(R.id.backBtn);
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
Intent intent = getIntent(); // 인텐트 객체 반환, 객체 안의 번들 객체 참조
processIntent(intent); // 인텐트를 전달해서 processIntent() 메소드에서 처리
}
private void processIntent(Intent intent) { // 번들 객체에서 꺼낸 후 TextView로 보여줌
if(intent != null) {
Bundle bundle = intent.getExtras();
ExampleData exampleData = bundle.getParcelable(EXAMPLE_DATA_KEY);
if(intent != null) {
tv.setText("제목 : " + exampleData.title + "\n" +"내용 : " + exampleData.contents);
}
}
}
}
|
cs |
피드백은 언제나 환영입니다.