[Android] Serializable vs Parcelable

๐Ÿ’ก 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

 

Parcelable ๊ตฌํ˜„ ์ƒ์„ฑ๊ธฐ  |  Kotlin  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Parcelable ๊ตฌํ˜„ ์ƒ์„ฑ๊ธฐ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. kotlin-parcelize ํ”Œ๋Ÿฌ๊ทธ์ธ์€ Parcelable

developer.android.com

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์„ ํ™œ์šฉํ•˜์—ฌ ๋‹จ์ ์„ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GitHub - GMLim/Android-Serialization-Test: Parcelable ๊ณผ ์ปค์Šคํ…€ ๋œ Serializable ์˜ ์†๋„๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

 

GitHub - GMLim/Android-Serialization-Test: Parcelable ๊ณผ ์ปค์Šคํ…€ ๋œ Serializable ์˜ ์†๋„๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

Parcelable ๊ณผ ์ปค์Šคํ…€ ๋œ Serializable ์˜ ์†๋„๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. Contribute to GMLim/Android-Serialization-Test development by creating an account on GitHub.

github.com

  • ์•„๋ž˜ ์ฝ”๋“œ๋Š” 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์ด ํšจ์œจ์ ์ž„์„ ์ฃผ์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Parcelable vs Serializable

 

Parcelable vs Serializable

Often, when we develop applications, we have to transfer data from one Activity to another. Of course, we can not do that directly. Theโ€ฆ

medium.com

 

Serializable ๊ทธ๋ฃน

  • ์ด ๊ทธ๋ฃน์€ Serializable์„ Parcelable์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ปค์Šคํ…€ํ•˜๋Š” ๊ฒฝ์šฐ ๋” ํšจ์œจ์ ์ž„์„ ์ฃผ์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค.

GitHub - GMLim/Android-Serialization-Test: Parcelable ๊ณผ ์ปค์Šคํ…€ ๋œ Serializable ์˜ ์†๋„๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

 

GitHub - GMLim/Android-Serialization-Test: Parcelable ๊ณผ ์ปค์Šคํ…€ ๋œ Serializable ์˜ ์†๋„๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

Parcelable ๊ณผ ์ปค์Šคํ…€ ๋œ Serializable ์˜ ์†๋„๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. Contribute to GMLim/Android-Serialization-Test development by creating an account on GitHub.

github.com

 

์ฐธ๊ณ 

https://medium.com/android-news/parcelable-vs-serializable-6a2556d51538

https://medium.com/@limgyumin/parcelable-vs-serializable-์ •๋ง-serializable์€-๋Š๋ฆด๊นŒ-bc2b9a7ba810

https://medium.com/android-news/parcelable-vs-serializable-6a2556d51538