Hun's Blog

Parcelable in Kotlin 본문

Language/Kotlin & Java

Parcelable in Kotlin

jhk-im 2020. 11. 7. 01:24

joaoalves.dev/posts/kotlin-playground/parcelable-in-kotlin-here-comes-parcelize/

 

Parcelable in Kotlin? Here comes Parcelize

Hey everyone, welcome to article number 5 in the series where we’re going to look into how to handle Parcelables in Kotlin.

joaoalves.dev

기본적으로 Parcelable이 사용되는 경우는  다른 Activity로 모델을 전달해야 할때이다. 

class ActivityA : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val intent = Intent(this, ActivityB::class.java)
        val person = Person("name", 32, "email@email.com", 1234)

        intent.putExtra("A_STRING", "some string")
        intent.putExtra("A_NUMBER", 1234)
        intent.putExtra("AN_OBJECT", person) // compilation error

        startActivity(intent)
    }
}

위코드에서 compilation error가 나는 이유는 Int와 String같은 원시타입은 바로 전달이 가능하지만 Person과 같은 모델은 그대로 전달할 수 없기 때문이다. 

모델을 전달하기 위한 몇가지 방법이 있다. 

1. Implement Serializable

 -> 효율적이며 구현이 쉽지만 reflection 기반으로 하기 때문에 성능이 상당히 좋지 않다. 

2. Json String

  -> 구현 가능하지만 GSON과 같은 라이브러리를 사용하고 있다면 최선의 선택은 아니다. 

3. Implement Parcelable

  -> 공식 문서에서 권장하는 방법이다. serialization 처럼 java 객체를 marshalling/unmarshalling

 

Parcelable이 최선의 선택이지만 이것은 모델을 변경할 때마다 업데이트 해야하는 많은 보일러플레이트 코드를 포함하고 있다.

이를 자바에선 AutoValue를 사용하여 해결하는데 Kotlin에선 어떻게 해결할까? 

data class Person(val name: String, val age: Int, val email: String, val phone: Long) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.readInt(),
        parcel.readString(),
        parcel.readLong())

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(name)
        parcel.writeInt(age)
        parcel.writeString(email)
        parcel.writeLong(phone)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Person> {
        override fun createFromParcel(parcel: Parcel): Person {
            return Person(parcel)
        }

        override fun newArray(size: Int): Array<Person?> {
            return arrayOfNulls(size)
        }
    }
}

Parcelable의 활용은 보일러플레이트 코드 관련이 깊다. Person이라는 작은 모델을 위해서 수십줄의 코드가 추가되었다. 

 

JetBrains introduced it in the Kotlin 1.1.4 release

@Parcelize
automatic Parcelable implementation generator. 
해당 주석을 추가하면 writeToParcel() / createFromParcel() 메서드가 자동으로 생성된다. 

아직 실험적인 feature이기 때문에 build.gradle 파일에 다음을 추가해야한다. 

androidExtensions { experimental = true }

위에 있던 코드를 다음과 같이 짧게 표현할 수 있다. 

@Parcelize
data class PersonParcelize(val name: String, 
                           val age: Int, 
                           val email: String, 
                           val phone: Long) : Parcelable

 

 

* reflection -> 클래스를 객체화 하지 않고서, 텍스트 설계도인 채로, 해당 클래스의 정보를 가져와서 활용하는 방법

* Structure -> Message 로 변경하는 작업이 Marshalling

  Message -> Structure 로 변경하는 작업은 UnMarshalling

* AutoValue -> 생산성을 향상시키기 위한 라이브러리라이며 클래스의 멤버 변수를 Getter, Setter가 아닌빌더 패턴을 추가하여 자동으로 Serialization 

'Language > Kotlin & Java' 카테고리의 다른 글

[JAVA] Generic이란 무엇인가?  (0) 2020.03.21
[JAVA] Hash란 무엇인가?  (2) 2020.03.21
[JAVA] MAP의 자료구조  (0) 2020.03.21
[JAVA] Call by value와 Call by reference  (0) 2020.03.21
[JAVA] abstract와 interface의 차이점  (1) 2020.03.21