이번 포스팅은 bundleOf()를 사용해서 Activity나 Fragment에 데이터를 더욱 더 쉽게 전달하는 방법에 대해 소개 합니다.
Setup
bundleOf()함수는 Android KTX중에 core-ktx에 있는 함수 입니다.
그래서 사용하기 전에 build.gradle에 core-ktx를 추가해 줘야 합니다.
이 포스팅을 작성했을 때 버전은 1.2.0 입니다.
dependencies {
implementation "androidx.core:core-ktx:1.15.0"
}
bundleOf()
bundleOf 함수는 key와 value가 쌍으로 이루어진 요소를 담고 있는 Bundle을 만들어서 리턴하는 함수 입니다.
함수는 Pair<String, Any?>를 파라미터로 전달 받고 Bundle을 리턴하는 형태로 되어 있습니다. 또한 vararg이기 때문에 ,
로 구분해서 여러 Pair를 전달 할 수 있습니다.
// Sample enum class
@Parcelize
enum class AndroidLanguage : Parcelable {
Java,
Kotlin
}
val bundle: Bundle = bundleOf(
"key1" to 5,
"key2" to 2.4f,
"key3" to "Hello World",
"key4" to AndroidLanguage.Kotlin
)
bundleOf() 함수는 내부에서 다양한 Type을 지원
하기 때문에 Type Casting을 직접 해서 넣어 줄 필요가 없습니다. 또한 Type 검사에 대한 우선순위
를 가지고 있기 때문에 Parcelable/Serializable 두개의 타입을 동시에 가지고 있는 Class도 Parcelable로 전달 할 수 있습니다.
fun bundleOf(vararg pairs: Pair<String, Any?>) = Bundle(pairs.size).apply {
for ((key, value) in pairs) {
when (value) {
null -> putString(key, null) // Any nullable type will suffice.
// Scalars
is Boolean -> putBoolean(key, value)
is Byte -> putByte(key, value)
is Char -> putChar(key, value)
is Double -> putDouble(key, value)
is Float -> putFloat(key, value)
is Int -> putInt(key, value)
is Long -> putLong(key, value)
is Short -> putShort(key, value)
// References
is Bundle -> putBundle(key, value)
is CharSequence -> putCharSequence(key, value)
is Parcelable -> putParcelable(key, value)
// Scalar arrays
is BooleanArray -> putBooleanArray(key, value)
is ByteArray -> putByteArray(key, value)
is CharArray -> putCharArray(key, value)
is DoubleArray -> putDoubleArray(key, value)
is FloatArray -> putFloatArray(key, value)
is IntArray -> putIntArray(key, value)
is LongArray -> putLongArray(key, value)
is ShortArray -> putShortArray(key, value)
// Reference arrays
is Array<*> -> {
val componentType = value::class.java.componentType
@Suppress("UNCHECKED_CAST") // Checked by reflection.
when {
Parcelable::class.java.isAssignableFrom(componentType) -> {
putParcelableArray(key, value as Array<Parcelable>)
}
String::class.java.isAssignableFrom(componentType) -> {
putStringArray(key, value as Array<String>)
}
CharSequence::class.java.isAssignableFrom(componentType) -> {
putCharSequenceArray(key, value as Array<CharSequence>)
}
Serializable::class.java.isAssignableFrom(componentType) -> {
putSerializable(key, value)
}
else -> {
val valueType = componentType.canonicalName
throw IllegalArgumentException(
"Illegal value array type $valueType for key \"$key\"")
}
}
}
// Last resort. Also we must check this after Array<*> as all arrays are serializable.
is Serializable -> putSerializable(key, value)
else -> {
if (Build.VERSION.SDK_INT >= 18 && value is Binder) {
putBinder(key, value)
} else if (Build.VERSION.SDK_INT >= 21 && value is Size) {
putSize(key, value)
} else if (Build.VERSION.SDK_INT >= 21 && value is SizeF) {
putSizeF(key, value)
} else {
val valueType = value.javaClass.canonicalName
throw IllegalArgumentException("Illegal value type $valueType for key \"$key\"")
}
}
}
}
}
기존 방식과 비교
기존에 Activity끼리 데이터를 주고 받을 때는 Intent에 putExtra로 key와 value를 넣어주는 방식을 사용 했습니다.
val intent = Intent(this, MainActivity::class.java)
intent.putExtra("key1", 5)
intent.putExtra("key2", 2.4f)
intent.putExtra("key3", "Hello World")
intent.putExtra("key4", AndroidLanguage.Kotlin)
하지만 위 처럼 넣게 되면 AndroidLanguage가 Parcelable이면서 Serializable이기 때문에 함수 Overload 에러가 발생하게 됩니다.
그래서 enum class를 전달 할 땐 AndroidLanguage.Kotlin as Parcelable
이렇게 type casting을 해줘야 합니다.
Activity
bundleOf()를 사용하게 된다면 더 깔끔하게 작성 할 수 있습니다.
val intent = Intent(this, MainActivity::class.java)
val bundle = bundleOf(
"key1" to 5,
"key2" to 2.4f,
"key3" to "Hello World",
"key4" to AndroidLanguage.Kotlin
)
intent.putExtras(bundle)
위 코드에서는 key4에 넣는 enum class에서 에러가 발생하지 않습니다.
그리고 bundleOf() 내부 구현을 보면 Serializable보다 Parcelable이 우선순위가 높기 때문에 Serializable로 들어갈 걱정을 하지 않아도 됩니다.
intent에 bundle을 넣을 때는 뒤에 s
가 있는 putExtras
함수를 사용하면 됩니다.
Fragment
fragment도 동일하게 bundle을 만들고 fragment에 arguments에 bundle을 넣어주면 됩니다.
val fragment = MainFragment()
val bundle = bundleOf(
"key1" to 5,
"key2" to 2.4f,
"key3" to "Hello World",
"key4" to AndroidLanguage.Kotlin
)
fragment.arguments = bundle
마무리
bundleOf()함수를 사용하면 코드를 더욱 간결하게 작성해서 가독성이 높게 만들 수 있으며 Type에 대한 걱정을 하지 않아도 되서 코드를 작성 할 때 걱정을 덜어줄 수 있습니다.
블로그 글에 대해 궁금한 점이 있다면 아래 카카오톡 오픈채팅에 들어와서 질문해주세요
Android Kotlin Compose QnA
open.kakao.com
'개발 > 안드로이드' 카테고리의 다른 글
(Android) 간단하게 Activity, Fragment 보여주기 (1) | 2025.05.09 |
---|---|
(Android) Dynamic App Icon (0) | 2024.02.21 |
(Android) 네이버/카카오 API 키 안전하게 관리하기 (0) | 2024.01.08 |