[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