안드로이드에서의 액티비티 간 Object를 전달하는 방법은 두 가지가 있다.
1. Serializable(직렬화)를 통한 방법
2. Parcelable interface를 통한 방법
이번 공부내용은 두 번째 방법인 Parcelable을 사용해서 액티비티 간 Object를 전달하는 법을 알아보겠다.
# Parcelable란?
- Parcel이라는 뜻을 먼저 해석해보면 소포, 꾸러미등으로 해석이 되고 Parcelable이라 함은 택배로 부칠 수 있는 정도로 해석이 가능하다.
- Android에서 지원해주는 SDK에 포함되어 있는 인터페이스이다.
- Serializable 대비 속도면에서 훨씬 빠르다.
# 기존 Parcelable 문제점
- Parcelable을 구현하는 것은 직접 구현해야 한다 그렇게 때문에 보일러 플레이트 코드(비슷한 코드가 반복되는 것)가 생기게 된다.
- 위와 같은 이유 때문에 Serializable에 비해 코드 작성 시간이 오래 걸리게 된다.
이러한 문제를 해결해줄 코틀린 parcelize 플러그인이 있어 parcelize를 사용해 액티비티간 객체 전달을 아래 예제를 통해 알아보자!
※ 본 예제는 viewbinding을 사용했으므로 viewbinding을 숙지하지 못하면 여기를 통해 먼저 학습하고 오는걸 추천한다.
이번 예제는 간단한 MainActivity에서 SubActivity로 유저 데이터(이름, 나이)를 data class를 통해 넘겨주는 예제이다.
# Plugins 추가 (모듈 수준)
plugins {
...
id("kotlin-parcelize")
}
# 넘겨줄 객체(data class) 생성
@Parcelize // Parcelable 구현을 위한 어노테이션 추가
data class UserData(
val name: String,
val age: Int
) : Parcelable // Parcelable 형으로 리턴
Parcelable 자동으로 구현 해주는 @Parcelize Annotaion을 data class 위에 추가해주고 뒤에 Parcelable을 implement 시킨다.
# xml 생성
<activity_main.xml>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="첫번째 액티비티"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/linearLayoutCompat"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@+id/btnSubmit"
app:layout_constraintTop_toBottomOf="@+id/textView">
<EditText
android:id="@+id/inputName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:autofillHints="이름 입력"
android:hint="이름 입력"
android:inputType="text" />
<EditText
android:id="@+id/inputAge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints="나이 입력"
android:hint="나이 입력"
android:inputType="number" />
</androidx.appcompat.widget.LinearLayoutCompat>
<Button
android:id="@+id/btnSubmit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="25dp"
android:layout_marginHorizontal="15dp"
android:text="SubActivity 호출"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<activity_sub.xml>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SubActivity">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="두번째 액티비티"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2">
<TextView
android:id="@+id/textName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이름 : "
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textAge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="나이 : "
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
# 메인액티비티에서 intent를 통해 SubActivity로 객체 전달
<MainActivity.class>
package com.example.parcelizeex
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.parcelizeex.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
private lateinit var userData: UserData
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding){
btnSubmit.setOnClickListener {
saveUserData() // userData에 데이터 저장
val intent = Intent(this@MainActivity,SubActivity::class.java)
intent.putExtra("USER_DATA",userData) // 기존과 동일하게 putExtra 로 전송
startActivity(intent)
}
}
}
private fun saveUserData(){
userData = UserData(
name = "${binding.inputName.text}",
age = "${binding.inputAge.text}".toInt()
)
}
}
여기서 봐야할거는 intent로 넘기는 과정에서 일반 String, Int 넘기는 거와 동일하게 putExtra(KEY, VALUS)로 전송한다.
# 서브액티비티에서 intent를 통해 값 받아오기
<SubActivity.class>
package com.example.parcelizeex
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.parcelizeex.databinding.ActivityMainBinding
import com.example.parcelizeex.databinding.ActivitySubBinding
class SubActivity : AppCompatActivity() {
private lateinit var binding : ActivitySubBinding
// getParcelableExtra 사용해 값 받아오기
private val userData: UserData? by lazy {
intent.getParcelableExtra("USER_DATA")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySubBinding.inflate(layoutInflater)
setContentView(binding.root)
with(binding){
userData?.let { userData ->
textName.text = "${userData.name}님"
textAge.text = "${userData.age}살"
}
}
}
}
여기서의 중요 포인트는 기존 String, Int 등 받을 때에는 get자료형 Extra로 받아왔지만 Parcelable 방식으로 넘겨준 객체는 getParcelableExtra(KEY)로 받아온다.
그리고 Null 체크를 꼭 해줘야 한다.
※ Array, ArrayList를 받아오고 싶다면 아래와 같은 속성들이 있으니 참고 하길 바란다.
또한 아래 사진을 보면Parcelable은 다양한 유형을 지원한다.
깃허브
https://github.com/JiSeokYeom/ParcelizeEx.git
GitHub - JiSeokYeom/ParcelizeEx
Contribute to JiSeokYeom/ParcelizeEx development by creating an account on GitHub.
github.com
참고
https://developer.android.com/kotlin/parcelize?hl=ko
https://kotlinworld.com/44
'안드로이드 공부 노트' 카테고리의 다른 글
[Android] DI(Dependncy Injection) 알아보기! (0) | 2023.02.05 |
---|---|
[Android] 안드로이드 전화번호 포맷 맞춰주기 (전화번호 사이에 하이픈(-) 넣기) (0) | 2022.12.28 |
[Android - Glide] 안드로이드 이미지 로드 라이브러리 Glide 사용법 - Kotlin (0) | 2022.10.09 |
[Android] 안드로이드 registerForActivityResult()란?(startActivityForResult derpecated 해결 방법) (0) | 2022.05.29 |
[Android]안드로이드 SharedPreferences란? (예제를 이용한 사용법) (0) | 2022.03.23 |