2019. 3. 6. 09:38ㆍProgramming/Android
[스마이트]일단 뼈대는 완성했다.를 만들면서 Activity간에 Data Class를 전달해야 할 일이 발생했다. 사실 아이템과 관련된 내용들을 전체 Activity에서 사용하기 때문에, 굳이 Data Class를 전달하지 않고도 사용할 방법을 찾으려면 찾을 수는 있었겠지만…
예전에는 Serializable
을 사용했던 걸로 기억하지만, Serializable
은 내부적으로 많은 리플렉션과 다량의 오브젝트를 생성하기 때문에, 안드로이드 앱의 전체적인 성능을 낮추며 배터리를 소모하는 원인이 된다고 한다. (Parcelable과 Serializable 비교, Charles 님) 물론 Kotlin
이 Java Wrapper는 아니지만, Serializable
을 사용하더라도 크게 다르지는 않을 듯 싶다. - (Kotlin, 어떻게 동작하나요, Chang W. Doh님)
Parcelable
을 적용하기 위해서는 사용할 Data Class가 Parcelable
을 상속받게끔 구현한 뒤, 생성자
, writeToParcel
, describeContents
, CREATOR
를 구현해주면 된다. Data Class를 Parcelable
Object로 전달한 뒤, 원래의 Data Class로 변환하여 사용하기 때문인 듯 하다. 구현하고나면 Parcelable을 사용하여, Object를 전달할 수 있다. - (Parcelable을 사용한 오브젝트 전달(Object serialization using Parcelable), ArsViator 님)
개인적으로는 Data Class 안에 Data Class가 포함되어있을 경우, 어떻게 처리해야할지에 대한 자료를 찾지 못했다. Data Class가 총 세 개 있었는데, 서로 계층구조를 이루고 있었다. 따로따로 구현하자니 생각보다 손이 많이 갔다. 하지만 JSON File에 손을 댈 경우 스마이트 홈페이지에서 데이터를 받아서 업데이트 하기 귀찮아지므로, 좀 더 편한 방법을 생각해야 했다.
물론 Data Class를 JSON Object의 형식에 맞춰서 작성할 필요는 없었다. 어차피 JSON Object는 읽어서 데이터를 생성할 때의 문제지, Data Class를 내 마음대로 정의한다고 문제가 될 일은 없었기 때문이다. 단지 문제에 직면했을 때 1차원적으로 생각했기 때문에 발생한 문제다. Data Class의 구조를 변경했다면, 오히려 구조가 쉬워질 수도 있었을 것이다.
아무튼 다시 원점으로 돌아와서, Kotlin 1.1.4
부터 추가된 Parcelize
을 이용해서 이를 쉽게 해결할 수 있었다.
An automatic
Parcelable
implementation generator. Declare the serialized properties in a primary constructor and add a@Parcelize
annotation, andwriteToParcel()
/createFromParcel()
methods will be created automatically
@Parcelize
annotation을 사용하면, writeToParcel()
/createFromParcel()
를 자동으로 구현해준다는 내용이다. 정말이지 편리하다. 이를 사용하기 위해서는 우선, build.gradle
파일에 다음의 코드를 추가해줘야 한다. experimental
이라는 이름이 좀 신경쓰이긴 하지만, 아무튼 이 값을 true
로 변경하면 된다.
androidExtensions {
experimental = true
}
그 다음에는 Parecelable
을 상속할 Data Class의 Primary constructor앞에 @Parcelize
를 붙여주기만 하면 된다. Data Class를 안에 Data Class가 포함된 경우에는 하위 Data Class에도 동일하게 @Parcelize
를 사용하면, 자동으로 구현이 된다. 다음은 이를 적용한 내용이다.
@Parcelize
data class MenuItem(
val Description:String,
val Description_kr:String,
val Value:String
):Parcelable
@Parcelize
data class ItemDescription(
val Description: String,
val Description_kr: String,
val menuItems: ArrayList<MenuItem>,
val SecondaryDescription: String,
val SecondaryDescription_kr: String
):Parcelable
@Parcelize
data class Item(
val ChildItemId:Int,
val DeviceName:String,
val IconId:Int,
val ItemDescription:ItemDescription,
val ItemId: Int,
val ItemTier: Int,
val Price: Int,
val RestrictedRoles: String,
val RestrictedRoles_kr: String,
val RootItemId: Int,
val ShortDesc: String,
val StartingItem: Boolean,
val Type: String,
val itemIcon_URL: String,
val ret_msg: String? = null
):Parcelable
@Parcelize
를 사용했을 때 발생할 수 있는 문제가 두 가지 있는데, 하나는 Kotlin 1.1.5
부터는 회피가 가능하다고 하며, 다른 하나는 Android 4.4
이하 버전의 사용자가 설치하지 못하는 상황이 발생할 수 있다는 내용이다. 지금 글을 작성하고 있는 시점(2019-03-06)에서는 이미 Android 4.4
의 지원이 끊긴 상태이므로 크게 문제는 되지 않으리라 생각하지만, 업무에 적용할 시에는 유의할 필요가 있다. - (Parcelable in Kotlin? Here comes Parcelize, Joao Alves 님)
참조:
Parcelable, Android Developers
Easy Parcelable in Kotlin, Zahidur Rahman Faisal 님
Kotlin Parcelable 플러그인 사용하기, Taehwan 님
[Android] Parcelable에 대한 쉬운 이해, 명동콜링 님
Is there a convenient way to create Parcelabe data classes in Android with Kotlin?, StackOverflow
'Programming > Android' 카테고리의 다른 글
[GCM to FCM Migration 삽질기 #1] 기존에 사용하던 GCM 코드 확인 (0) | 2019.04.08 |
---|---|
[Android] NavigationMenu에 checkbox/switch 등의 UI 추가하기 (0) | 2019.03.17 |
WebView에서 Alert가 동작하지 않을 때 (0) | 2019.03.05 |
[Android/Kotlin] RecyclerView에 Divider 구분선 넣기 (0) | 2019.02.27 |
Android에서 사용하는 단위 정리 (0) | 2019.02.19 |