1. Parcelable
- Intent를 통해 객체를 전달할 때는 Parcelable 인터페이스를 구현한 객체만 가능하다.
- Parcelable 인터페이스는 전달받은 쪽에서 객체를 복원할 때 필요한 정보를 가진 부분을 의미한다.
- 안드로이드에서는 액티비티 - 액티비티간에 "객체 자체"를 전달할 수는 없고, "객체 안에 있는 값들을 전달"해서 받는 액티비티에서 "똑같은 객체를 새로 생성"해서 마치 객체가 전달 된 것 마냥 하는것이다.
-> 왜 이러는걸까?
1. 안드로이드의 4대 구성요소들은 모두 독립적인 실행단위이기 때문에.
2. 다른 어플리케이션이 갖고있는 4대 구성요소를 실행시키는것도 가능하기 때문에.
2. Parcelable 인터페이스를 구현한 클래스
1. class TestClass : Parcelable 인터페이스 구현
2. override fun writeToParcel(dest: Parcel?, flags: Int)
- 안드로이드에서 객체를 전달할 때는 객체가 전달되는게 아니라 Parcel 클래스 타입이 전달된다.
- 그래서 전달하고 싶은 데이터들을 Parcel 객체에 넣어주면 뽑아쓸 수 있다.
- 데이터를 넣은 순서와 나중에 빼는 순서가 같아야 한다.
- writeXXX()로 데이터를 넣는다.
4. CREATOR 변수 선언
- 나중에 data를 복원하는 쪽에서 안드로이드OS는 이 TestClass가 가지고 있는 CREATOR 라는 멤버를 갖고 메서드를 호출한다.
- 이 때 이 CREATOR 멤버는 Static으로 정의되어 있어야한다.
*Kotlin에서의 상수
- Kotlin에서 상수를 사용할 땐 companion object 블록을 써서 한다.
- Kotlin에서 상수를 정의하는데 이를 안드로이드OS에서 쓸 경우 @JvmField를 붙여줘야한다.
- val CREATOR : Parcelable.Creator<TestClass> = object : Parcelable.Creator<TestClass>
5. CREATOR 변수에서 createFromParcel() 오버라이딩
- 객체를 복원하는 메서드.
- 매개변수에 Parcel 객체가 전달되기 때문에, 여기서 readXXX()로 데이터를 읽는다.
- 복원된 Parcel 객체를 반환 한다.
6. 만일 Parcel 객체가 하나가 아닌 배열로 들어왔을 땐 newArray() 를 오버라이딩해서 TestClass배열을 만들고 NULL로 채워준다.
package com.example.hyunndy_01
import android.os.Parcel
import android.os.Parcelable
// 1. Parcelable 인터페이스 구현.
class TestClass : Parcelable{
var data10 : Int = 0
var data20:String? = null
// 4.
// 나중에 data를 복원하는 쪽에서 안드로이드OS는 이 TestClass가 가지고 있는 creater라는 멤버를 갖고 메서드를 호출한다. 이 때 이 Creater 멤버는 Static으로 정의되어 있어야한다.
// Kotlin에서 상수를 사용할 땐 companion object를 써서 한다.
companion object
{
// 5.
// Kotlin에서 상수를 정의하는데 이를 안드로이드OS에서 쓸 경우 @JvmField를 붙여줘야한다.
@JvmField
// 이 이름은 반드시 CREATOR로 되있어야 한다.
val CREATOR : Parcelable.Creator<TestClass> = object : Parcelable.Creator<TestClass>
{
// 6. 객체를 복원하는 메서드.
override fun createFromParcel(source: Parcel?): TestClass {
val test = TestClass()
// 객체 읽음
test.data10 = source?.readInt()!!
test.data20 = source?.readString()
// 객체 복원
return test
}
// 7.
// 객체 하나가아니라 객체들의 배열이 전달되었을 경우..
// 이 메서드가 먼저 불려서 배열이 만들어지고 각각의 멤버를 복원하기위해서 CreateFromParcel이 호출이 된다.
override fun newArray(size: Int): Array<TestClass?> {
// TestClass타입의 배열을 만드는데 그 안에 NULL값을 채워넣는다는것이다.
return arrayOfNulls<TestClass>(size)
}
}
}
// 2.
// 안드로이드에서 객체를 전달할 때는 객체가 전달되는게 아니라 Parcel 클래스 타입이 전달된다.
// 그래서 전달하고 싶은 데이터들을 Parcel 객체에 넣어주면 뽑아쓸 수 있다.
override fun writeToParcel(dest: Parcel?, flags: Int) {
// 3.
// 데이터를 넣은 순서와 나중에 빼는 순서가 같아야 한다.
dest?.writeInt(data10)
dest?.writeString(data20)
}
override fun describeContents(): Int {
return 0
}
}
3. Main Activity에서 Second Activity로 객체 전달.
1. Parcelable 인터페이스를 구현한 클래스 객체를 만든다.
2. 데이터를 세팅한다.
3. Intent를 생성하고 클래스 객체를 putExtra()로 넣은 후 보낸다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button2.setOnClickListener { view ->
// 8. Parcelable 인터페이스를 구현한 클래스 객체를 만든다.
var t1 = TestClass()
t1.data10 = 100
t1.data20 = "문자열2"
var intent = Intent(this, SecondActivity::class.java)
// 9. intent에 TestClass 객체를 넣는다. (정확히는 TestClass가 가진 값들)
intent.putExtra("test", t1);
startActivityForResult(intent, SECOND_ACTIVITY)
}
}
4. Second Activity에서 객체 복원.
1. Intent.getParcelableExtra<객체>("Main에서 전달받은 별명")으로 복원한다.
2. 전달받은 데이터로 막 한다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
// 10. 메인 액티비티에서 Intent로 보낸 객체들의 값들을 받는다!
var t1 = intent.getParcelableExtra<TestClass>("test")
textView2.text = "t1.data1 : ${t1.data10}\n"
textView2.append("t2.data2 : ${t1.data20}")
}
5. Second Activity에서도 Main Activity로 Intent를 통해 객체 전달하기.
1. Parcelable 인터페이스를 구현한 클래스 객체를 생성한다.
2. 데이터를 세팅하고, Intent를 생성하고 putExtra()로 넣은 후 setResult()로 resultCode와 Intent객체를 넣어서 보낸다.
button10.setOnClickListener { view ->
// 11. main으로도 보내기.
var t2 = TestClass()
t2.data10 = 200
t2.data20 = "문자열2"
var intent2 = Intent()
intent2.putExtra("test2", t2)
setResult(Activity.RESULT_OK, intent2)
finish()
}
6. Main Activity에서 데이터 복원하기.
1. OnActivityResult()의 매개변수로 Intent가 넘어오면, getParcelabeExtra()를 통해 데이터를 뽑는다.
// 12. second 액티비티에서 보낸 데이터 받기.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(resultCode == Activity.RESULT_OK)
{
var t2 = data?.getParcelableExtra<TestClass>("test2")
textView.text = "t2.data1 : ${t2?.data10}\n"
textView.append("t2.data2 : ${t2?.data20}")
}
}
'Deperecated > Android_강의' 카테고리의 다른 글
안드로이드 - Activity Action (0) | 2020.02.19 |
---|---|
안드로이드 - 다른 애플리케이션의 액티비티 실행하기 (0) | 2020.02.18 |
안드로이드 - 데이터 전달하기 (0) | 2020.02.18 |
안드로이드 - OnResultActivity (0) | 2020.02.18 |
안드로이드 - 안드로이드 4대 구성 요소 - Activity 실행하기 (0) | 2020.02.18 |