๐ก Android์์ ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ๋ Serializable๊ณผ Parcelable๋ฅผ ๋น๊ตํ์ฌ ์ ๋ฆฌํ์์ต๋๋ค!
๊ฐ์
- Serializable๊ณผ Parcelable์ Android์์ ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ์ฌ ๋ค๋ฅธ ์กํฐ๋นํฐ๋ ์๋น์ค๋ก ์ ๋ฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
- ๊ฐ ๋ฐฉ์์ ์ฅ๋จ์ ์ด ์์ผ๋ฉฐ, ์ํฉ์ ๋ฐ๋ผ ์ ํฉํ ๋ฐฉ์์ ์ ํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
Serializable
- Java์ ํ์ค ์ง๋ ฌํ ๋ฐฉ์์ผ๋ก Android์์ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
- ํน๋ณํ ๋ฉ์๋ ๊ตฌํ์ ์๊ตฌํ์ง ์๋ ์ธํฐํ์ด์ค์ด๋ฉฐ, ๊ฐ์ฒด๊ฐ ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ฉด Java์ ๊ธฐ๋ณธ ์ง๋ ฌํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import java.io.Serializable
data class User(val id: Int, val name: String) : Serializable
Serializable ๋ฐ์ดํฐ ์ ๋ฌ
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// User ๊ฐ์ฒด ์์ฑ
val user = User(1, "Bob")
// Intent๋ฅผ ํตํด User ๊ฐ์ฒด ์ ๋ฌ
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra("user", user as Serializable)
}
startActivity(intent)
}
}
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
// ์ ๋ฌ๋ User ๊ฐ์ฒด ๋ฐ๊ธฐ
val user = intent.getSerializableExtra("user") as? User
user?.let {
// User ๊ฐ์ฒด ์ฌ์ฉ
println("User ID: ${it.id}, Name: ${it.name}")
}
}
}
์ฅ์
- ๊ตฌํํ๊ธฐ ๋งค์ฐ ์ฝ๊ณ ๊ฐํธํฉ๋๋ค.
- ๋ณต์กํ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๋ ์ฝ๊ฒ ์ง๋ ฌํํ ์ ์์ต๋๋ค.
๋จ์
- ๋น๊ต์ ๋๋ฆฐ ์ฑ๋ฅ์ ๊ฐ์ง๊ณ ์๊ณ , Reflection์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋๋ฆฌ๊ณ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ด ๋ง์ต๋๋ค.
- [Reflection] : ๊ฐ์ฒด๋ฅผ ๊ฒ์ฌํ๊ณ ์กฐ์ํ๋ ๋ฉ์ปค๋์ฆ์ผ๋ก ํ๋ก๊ทธ๋จ ์คํ ์ค์ ๊ฐ์ฒด๋ฅผ ๋์ ์ผ๋ก ์กฐ์ํ ์ ์๋ ๊ธฐ๋ฅ์ ํฉ๋๋ค.
- ์ง๋ ฌํ๋ ํ์ผ ํฌ๊ธฐ๊ฐ ์๋์ ์ผ๋ก ํฌ๊ณ , ์ง๋ ฌํ ๊ณผ์ ์์ ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ๋๋ฉด InvalidClassException์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
- ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ serialVersionUID๋ฅผ ๊ด๋ฆฌํด์ผ ํฉ๋๋ค.
Parcelable
- Android์ ํนํ๋ ์ง๋ ฌํ ๋ฐฉ์์ผ๋ก Google์์ Android์ ์ฑ๋ฅ์ ์ํด ์ค๊ณํ์์ต๋๋ค.
- Parcelable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ธฐ ์ํด writeToParcel(), describeContents()์ ๊ฐ์ ๋ฉ์๋๋ฅผ ์ง์ ๊ตฌํํด์ผ ํฉ๋๋ค.
- CREATOR๋ผ๋ ์ ์ ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ณต๊ตฌ ๋ก์ง์ ์ ์ํด์ผ ํฉ๋๋ค.
import android.os.Parcel
import android.os.Parcelable
data class User(val id: Int, val name: String) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString() ?: ""
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(id)
parcel.writeString(name)
}
override fun describeContents(): Int = 0
companion object CREATOR : Parcelable.Creator<User> {
override fun createFromParcel(parcel: Parcel): User {
return User(parcel)
}
override fun newArray(size: Int): Array<User?> {
return arrayOfNulls(size)
}
}
}
Parcelable ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐ
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// User ๊ฐ์ฒด ์์ฑ
val user = User(1, "Alice")
// Intent๋ฅผ ํตํด User ๊ฐ์ฒด ์ ๋ฌ
val intent = Intent(this, DetailActivity::class.java).apply {
putExtra("user", user)
}
startActivity(intent)
}
}
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
// ์ ๋ฌ๋ User ๊ฐ์ฒด ๋ฐ๊ธฐ
val user = intent.getParcelableExtra<User>("user")
user?.let {
// User ๊ฐ์ฒด ์ฌ์ฉ
println("User ID: ${it.id}, Name: ${it.name}")
}
}
}
์ฅ์
- Android์์ ์์คํ ์ง๋ ฌํ์ ์ญ์ง๋ ฌํ์ ์ฑ๋ฅ์ ์ต์ ํํ์ฌ, Serializable๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ณ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ ๋๋ค.
๋จ์
- ๋ณต์กํ๊ณ ๊น๋ค๋ก์ด ๊ตฌํ๊ณผ ์๋์ผ๋ก ์ง๋ ฌํ์ ๊ฐ์ฒด๋ฅผ ๋ณต์ํ๋ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
- ๋ณต์กํ ๊ณ์ธต ๊ตฌ์กฐ์ ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ๊ธฐ ์ด๋ ต์ต๋๋ค.
- ๋ชจ๋ ๊ฐ์ฒด๊ฐ Parcelable์ ๊ตฌํํด์ผ ํ๋ฏ๋ก, ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ฝ๋์ ์์กดํ๋ ๊ฐ์ฒด๋ ์ง๋ ฌํ๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
Parcelable ๋จ์ ๊ทน๋ณตํ๊ธฐ
- Parcelable์ ๋ณต์กํ๊ณ ๊น๋ค๋ก์ด ๊ตฌํ์ด๋ผ๋ ํฐ ๋จ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ํ์ง๋ง ์๋๋ก์ด๋ ๊ณต์ ๋ฌธ์์์๋ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๊ณต์ ํ๋ฌ๊ทธ์ธ์ ํ์ฉํ๋ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค.
https://developer.android.com/kotlin/parcelize#kts
Parcelize ์ด๋ ธํ ์ด์ ์ฌ์ฉ
- Kotlin์์ ์ ๊ณตํ๋ kotlin-parcelize ํ๋ฌ๊ทธ์ธ์ ํตํด ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ์๋์ผ๋ก Parcelable์ ๊ตฌํํ ์ ์์ต๋๋ค.
- ๊ด๋ จ ์์กด์ฑ์ ์ถ๊ฐํฉ๋๋ค.
plugins {
id 'kotlin-parcelize' // ์์กด์ฑ ์ถ๊ฐ
}
- ์๋์ ๊ฐ์ด @Parcelize ์ด๋ ธํ ์ด์ ์ ๋ฐ์ดํฐ ํด๋์ค์ ์ ์ฉํ๋ฉด ํด๋น ํด๋์ค๊ฐ ์๋์ผ๋ก Parcelable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ฒ ๋ฉ๋๋ค.
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class User(val id: Int, val name: String) : Parcelable
์ด์ ์?
- ๋ณต์กํ ๊ตฌํ์ ๋จ์ํํ ์ ์์ผ๋ฉฐ, ์๋์ผ๋ก ์์ฑํ ๋ ๋ฐ์ํ ์ ์๋ ์ค์๋ฅผ ์ค์ด๊ฒ ๋ฉ๋๋ค.
Serializable์ ๋จ์ ๊ทน๋ณตํ๊ธฐ
- ์ผ๋ฐ์ ์ผ๋ก Serializable์ Parcelable๋ณด๋ค ๋๋ฆฐ ์ฑ๋ฅ์ ๋ณด์ ๋๋ค.
- ํ์ง๋ง ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก Serializable์ ํ์ฉํ์ฌ ๋จ์ ์ ๊ทน๋ณตํ ์ ์์ต๋๋ค.
- ์๋ ์ฝ๋๋ Serializable์์ ์๋์ผ๋ก ์ฒ๋ฆฌ๋๋ ์ง๋ ฌํ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉ์๊ฐ ์ปค์คํ ์ผ๋ก ๊ตฌํํ ๋ฐฉ์์ผ๋ก ์์ ํ์์ต๋๋ค.
private void writeObject(java.io.ObjectOutputStream out)
throws IOException;
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;
- ์ด๋ฅผ ํตํด Serializable์ ํ์ฉํ ๋ Java์ ์๋ ์ง๋ ฌํ ํ๋ก์ธ์ค๋ฅผ ํตํ ๋ง์ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์ค์ผ ์ ์์ต๋๋ค.
- ์ด๋ฌํ ํน์ ํด๋์ค ์ฒ๋ฆฌ ๋ก์ง์ ๊ตฌํํ๋ฉด Serializable์ด Parcelable ๋ณด๋ค ๋์ ์๋๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
์ ๋ฆฌ
- ์ค์ ๊ฐ๋ฐ์์ Parcelable์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฑ๋ฅ ๋ฉด์์ ๋ ์ ๋ฆฌํ์ง๋ง, ๊ฐ๋จํ ์์ ์ด๋ ํน์ ๊ฒฝ์ฐ์๋ Serializable์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ํ์ง๋ง ๋ ๊ฒฝ์ฐ ๋ชจ๋ ๋จ์ ์ด ์กด์ฌํ๋ฉฐ, ๋จ์ ์ ํด๊ฒฐํ ๋ฐฉ๋ฒ ์ญ์ ์กด์ฌํฉ๋๋ค.
- ์ด๋ก ์ธํด ์ด๋ ๊ฒ์ด ๋ ํจ์จ์ ์ธ์ง ๋น๊ตํ๋ ๊ทธ๋ฃน์ด ์๊ธฐ๊ธฐ๋ ํ์์ต๋๋ค.
Parcelable ๊ทธ๋ฃน
- ์ด ๊ทธ๋ฃน์ ํ ์คํธ๋ฅผ ํตํด ์ฑ๋ฅ์ ๋น๊ตํ์ฌ Parcelable์ด ํจ์จ์ ์์ ์ฃผ์ฅํ์์ต๋๋ค.
Serializable ๊ทธ๋ฃน
- ์ด ๊ทธ๋ฃน์ Serializable์ Parcelable์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ปค์คํ ํ๋ ๊ฒฝ์ฐ ๋ ํจ์จ์ ์์ ์ฃผ์ฅํ์์ต๋๋ค.
์ฐธ๊ณ
https://medium.com/android-news/parcelable-vs-serializable-6a2556d51538
https://medium.com/android-news/parcelable-vs-serializable-6a2556d51538