프로그래밍(programming)/안드로이드(android)

[210618] 안드로이드 Parcelable 로 데이터 전달하기

하빌리즘 2021. 6. 18. 15:21
반응형

 액티비티에서 다른 액티비티로 데이터를 전달해야하는 경우가 상당히 자주 있다. 

이렇게 데이터를 다른 액티비티로 전달할 때에는 '인텐트(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

초기 실행 화면
데이터 입력 후 전송 버튼 누르기

 

최종 화면

 

피드백은 언제나 환영입니다. 

반응형