はじめに
今までふわっとやってきた画面間の値渡しについて書こうと思います!Bundle
ってなんやねん?とか Serializable
と Parcelable
ってなんやねん?てことについて記載します。
Bundle
Weblio で意味を調べると下記。たぶんか「包み」、「かたまり」あたりが近いような気がする。
(通例真ん中をくくった)束、管束(かんそく)、包み、かたまり、一団、大金
Activity
の値保持や Activity
間の値渡し、Fragment
への値渡しなどのときに使われる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// この引数とか override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } // この引数とか override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment // argument も Bundle return inflater.inflate(R.layout.fragment_main, container, false) } // これも内部的にBundleを持ってるらしい val intent = Intent(this, SecondActivity::class.java).apply { putExtra("hoge_key", "hoge") } startActivity(intent,) |
下記のように色々な値を扱える
1 2 3 4 5 6 7 8 9 10 11 |
// putでも値設定可 val bundle = bundleOf( "key1" to "String", "key2" to 0, "key3" to true ) // 値取得 val value1 = bundle.getString("key1") val value2 = bundle.getInt("key2") val value3 = bundle.getBoolean("key3") |
なんかもっと色々入れれそう(下記参考)
Serializable
String
, Int
などを渡すのは簡単ですが独自のオブジェクトを渡す場合はどうすればいいのかというと Serializable
を使うと簡単にできます。Srializable
は下記のように空の interface
なのでこいつを対象のクラスに適応するだけで使えます。
1 2 |
public interface Serializable { } |
実装はこんな感じ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 値送信側 val hoge = Hoge("hogehoge", 12, Foo("foo"), listOf(Piyo("1"), Piyo("2"))) val intent = Intent(this, SecondActivity::class.java).apply { putExtra("hoge_key", hoge) } startActivity(intent) // 値受信側 val hoge = intent.getSerializableExtra("hoge_key") as Hoge Log.d("TAG", hoge.toString()) // 独自オブジェクト data class Hoge(val hogehoge: String, val fugafuga: Int, val foo: Foo, val piyos: List<Piyo>) : Serializable data class Foo(val foo: String) : Serializable data class Piyo(val piyo: String) : Serializable |
これだけ!とっても簡単!!
Serializable
詳細は下記参考
Androidデベロッパー:Serializable
Parcelable
Parcelable
も独自のオブジェクトを渡す場合に使えますが Srializable
よりも結構複雑です。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
// 値送信側 val hoge = Hoge("hogehoge", 12, Foo("foo"), listOf(Piyo("1"), Piyo("2"))) val intent = Intent(this, SecondActivity::class.java).apply { putExtra("hoge_key", hoge) } startActivity(intent) // 値受信側 val hoge = intent.getParcelableExtra("hoge_key") as Hoge Log.d("TAG", hoge.toString()) // 独自オブジェクト data class Hoge(val hogehoge: String, val fugafuga: Int, val foo: Foo, val piyos: List<Piyo>) : Parcelable { override fun writeToParcel(dest: Parcel, flags: Int) { dest.writeString(hogehoge) dest.writeInt(fugafuga) dest.writeParcelable(foo, flags) dest.writeParcelableList(piyos, flags) } override fun describeContents(): Int { return 0 } companion object { @JvmField val CREATOR: Parcelable.Creator<Hoge> = object: Parcelable.Creator<Hoge> { override fun createFromParcel(parcelIn: Parcel): Hoge { return Hoge(parcelIn.readString() ?: "", parcelIn.readInt(), parcelIn.readParcelable<Foo>(Foo::class.java.classLoader) ?: Foo(""), parcelIn.readParcelableList(mutableListOf(), Piyo::class.java.classLoader) ) } override fun newArray(size: Int): Array<Hoge?> { return arrayOfNulls(size) } } } } data class Foo(val foo: String) : Parcelable { override fun writeToParcel(dest: Parcel, flags: Int) { dest.writeString(foo) } override fun describeContents(): Int { return 0 } companion object { @JvmField val CREATOR: Parcelable.Creator<Foo> = object: Parcelable.Creator<Foo> { override fun createFromParcel(parcelIn: Parcel): Foo { return Foo(parcelIn.readString() ?: "") } override fun newArray(size: Int): Array<Foo?> { return arrayOfNulls(size) } } } } data class Piyo(val piyo: String) : Parcelable { override fun writeToParcel(dest: Parcel, flags: Int) { dest.writeString(piyo) } override fun describeContents(): Int { return 0 } companion object { @JvmField val CREATOR: Parcelable.Creator<Piyo> = object: Parcelable.Creator<Piyo> { override fun createFromParcel(parcelIn: Parcel): Piyo { return Piyo(parcelIn.readString() ?: "") } override fun newArray(size: Int): Array<Piyo?> { return arrayOfNulls(size) } } } } |
めっちゃ書かないといけない!あと下記サイトにあるように null 許容にすると色々めんどくさいらしい。。。
【android】まれにレビューで指摘するParcelableについて
Parcelable
詳細は下記参考
Androidデベロッパー:Parcelable
SerializableとParcelableの使い分け
結局 Serializable
と Parcelable
どっちを使えばいいんだ?となりますが画面間で値渡しをしたい!とかアプリ内のみであれば Serializable
でいいかと思います。Parcelable
はアプリ間でも値を渡すときに使えばいいと思います。
でもぶっちゃけアプリ間で値をやり取りする場合はアプリ間の Parcelable
のカスタムクラスの実装を揃えないといけないのであまり使い勝手は良くないように思います。。。
おわりに
なんとなく Serializable
は java.io.Serializable
にあって、Parcelable
は android.os.Parcelable
にあったので Android では Parcelable
使った方がいいのかなと思いましたがきっとそんなことはないです!
私の結論としては Parcelable
はなんかめんどくさいので全部 Serializable
でいいと思います!!
参考
- Androidデベロッパー:Parcelable と Bundle
- Android SDKの,ParcelableとSerializableの違いを比較 - Intentで独自オブジェクトを運搬する際,役立つのはどちら?
- Kotlin Parcelable について
- 【android】まれにレビューで指摘するParcelableについて
- Androidデベロッパー:Parcelable
- Androidデベロッパー:Serializable
コメント