출처: https://www.edwith.org/boostcourse-android/lecture/17066/
1. Serializable & Parcelable
부가데이터
부가데이터는 시스템에서 건드리지 않고 전달만 되며 인텐트 안에 번들(Bundle) 객체가 들어가 있어
그 안에 데이터를 넣을 때는 putExtra() 메서드, 데이터를 가져올 때는 getExtra() 메소드를 사용한다.
배경
Integer, String과 같은 기본 자료형들이 아닌 아래의 Person과 같이 직접 정의하는 객체가 있다.
1 2 3 4 5 6 | public class Person { String name; int age; String phoneNumber; String address; } | cs |
Person과 같이 여러 개의 속성이 들어가 있는 객체의 정보들을 전달하려 할 때 Person 클래스 자체를 putExtra(), getExtra()할 수 없다.
즉, 기본 자료형이 아닌 객체는 전달할 수 없기 때문에, 속성마다 일일이 putExtra(), getExtra()를 나누어 넣어야 하는 불편함이 있다.
그렇기 때문에 이 경우에는 Person 클래스 객체를 바이트 코드로 변환하는 직렬화(Serialization) 작업을 거쳐야 한다.
직렬화: http://qlyh8.tistory.com/97
직렬화 방법
표준 자바 인터페이스인 Serializable 객체를 이용해 부가데이터로 넣어 전달할 수 있다.
Serializable보다 좀 더 메모리 용량을 적게 차지하는 Android 전용 인터페이스인 Parcelable 객체를 만들어 전달할 수도 있다.
ArrayList와 같은 객체들은 이미 Serializable 인터페이스를 구현하고 있으므로 그대로 부가데이터로 추가할 수 있으며,
그 외에 Person과 같이 직접 정의하는 객체들은 Parcelable 인터페이스를 구현한 후 부가데이터로 추가한다.
성능
Parcelable는 안드로이드 개발에 최적화 되어 있기 때문에 Serializable 보다 속도가 더 빠르다.
Serializable은 Reflection 방법을 사용하여 직렬화를 하는데, Parcelable 은 프로그래머가 직접 직렬화를 구현하기 때문에 빠르다.
** Reflection
Java Class 파일은 Byte code로 컴파일되며, 실행시간에 이 Byte code가 해석되어 실행된다.
이 Byte code에는 Class에 대한 모든 정보를 포함하고 있다.
Reflection은 구체적인 Class 타입을 알지 못해도, 컴파일된 바이트 코드를 통해 역으로 클래스에 정보를 알아내어
클래스를 사용할 수 있는 기법을 말한다.
2. 실행 결과 화면
3. MainActivity.java
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 | package com.tistory.qlyh8.pracitice; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), SubActivity.class); // Serializable 객체 이용 ArrayList<String> names = new ArrayList<>(); names.add("aaa"); names.add("bbb"); intent.putExtra("names", names); // Parcelable 객체 이용 SimpleData data = new SimpleData(100, "ccc"); intent.putExtra("data", data); startActivityForResult(intent, 101); } }); } } | cs |
4. SubActivity.java
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 44 45 46 | package com.tistory.qlyh8.pracitice; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.util.ArrayList; public class SubActivity extends AppCompatActivity { Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub); button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); Intent intent = getIntent(); if(intent != null){ // ArrayList 와 같은 객체들은 이미 Serializable 인터페이스를 구현하고 있어 그대로 부가데이터로 추가할 수 있다. ArrayList<String> names = (ArrayList<String>) intent.getSerializableExtra("names"); if(names != null){ Toast.makeText(getApplicationContext(), "리스트 개수: " + names.size(), Toast.LENGTH_LONG).show(); } // Parcelable 객체는 Serializable 보다 좀 더 메모리 용량을 적게 차지한다. // SimpleData 와 같이 직접 정의하는 객체들은 Parcelable 인터페이스를 구현한 후 부가데이터로 추가한다. SimpleData data = intent.getParcelableExtra("data"); if(data != null){ Toast.makeText(getApplicationContext(), "SimpleData: " + data.number + ", " + data.message, Toast.LENGTH_LONG).show(); } } } } | cs |
5. SimpleData.java
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 44 45 46 47 48 49 50 | package com.tistory.qlyh8.pracitice; import android.os.Parcel; import android.os.Parcelable; // Parcel 은 SimpleData 안에 데이터를 다른 곳에 전달할 때 사용되는 객체이다. public class SimpleData implements Parcelable { int number; String message; public SimpleData(int number, String message) { this.number = number; this.message = message; } // Parcel 에서 SimpleData 안에 들어가 있는 변수를 read 로 복원한다. public SimpleData(Parcel src){ number = src.readInt(); message = src.readString(); } // 역직렬화(바이트 스트림을 원래 데이터 객체로 변환)할 때 사용되어진다. public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){ // 필수 메서드. parcel된 데이터를 다시 원래대로 만들어 준다. public SimpleData createFromParcel(Parcel src){ return new SimpleData(src); } // 필수 메서드. Parcel.createTypeArray()를 호출했을때 불린다. public SimpleData[] newArray(int size){ return new SimpleData[size]; } }; // Parcel의 내용을 기술한다. // FileDescriptor 같은 특별한 객체가 들어가면 이 부분을 통해서 알려줘야한다. // 보통은 0을 리턴해준다. @Override public int describeContents() { return 0; } // SimpleData 를 Parcel 로 바꾼다. (Parcel 안에 데이터를 넣는다.) @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(number); //number 값을 write dest.writeString(message); // message 값을 write } } | cs |
'Android' 카테고리의 다른 글
액티비티 수명주기 (Activity Lifecycle) - (2) (0) | 2018.05.19 |
---|---|
액티비티 수명주기 (Activity Lifecycle) - (1) (0) | 2018.05.19 |
애플리케이션 구성요소와 액티비티 전환 (2) (0) | 2018.05.19 |
애플리케이션 구성요소와 액티비티 전환 (1) (0) | 2018.05.19 |
Android Studio와 Git 연동하기 (0) | 2018.05.18 |