アゲブログ

プログラマーです。

Parcelableについて

Parcelableとは?

独自のデータクラスのインスタンスをBundleで保存したりIntentに渡す際に使用するインターフェース。 Serializableインターフェースを実装することでも同じことが実現できるが、Parcelableを用いるほうが効率が良いとのこと。

実装例

データクラス

Parcelableインターフェースを実装したクラスを作成する。

class User(
    var age: Int,
    var name: String
) : Parcelable {

    constructor(parcel: Parcel) : this(
        parcel.readInt(),
        parcel.readString() ?: ""
    )

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        if (dest != null) {
            dest.writeInt(this.age)
            dest.writeString(this.name)
        }
    }

    override fun describeContents() = 0

    companion object CREATOR : Parcelable.Creator<User> {

        override fun createFromParcel(parcel: Parcel) = User(parcel)

        override fun newArray(size: Int): Array<User?> = arrayOfNulls(size)
    }
}

以下のメソッドを実装する必要がある。

writeToParcel(Parcel, Int)

メンバ変数の保存を行う。

describeContents(Int)

通常は0を返すようにする。ParcelにFileDescriptorを保存する場合はParcelable.CONTENTS_FILE_DESCRIPTORを返す。

また、Parcelable.Creatorインターフェースを実装したCREATORというコンパニオンオブジェクトを保持しなければならない。

Bundleでの保存・復元方法

onSaveInstanceState(Bundle)Bundle#putParcelable(String, Parcelable)で保存する。

そして、onCreate(Bundle)もしくはonRestoreInstanceState(Bundle)Bundle#getParcelable(String)を実行してインスタンスを復元することができる。

class MainActivity : AppCompatActivity() {

    lateinit var user: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        this.user = if (savedInstanceState != null) {
            savedInstanceState.getParcelable("user")
        } else {
            User(0, "")
        }

        // 省略...
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)

        outState?.putParcelable("user", this.user)
    }
}

インテントでの受け渡し

渡す側

val user = User(10, "aaa")
val intent = Intent(this, AnotherActivity::class.java)
intent.putExtra("user", user)
startActivity(intent)

受け取り側

val user = intent.getParcelableExtra<User>("user") // user.age = 10, user.name = "aaa"

参考