記録

記録

Bundleに独自クラスを保存したい

fragmentを使って画面遷移する時にデータを渡したい場合なんかによく使うBundleですが、データを格納しておく独自クラスをそのまま入れたい時があります。 そういう時は通常のクラスでしたらParcelableを実装すれば bundle.putParcelable(key, val); でそのまま格納できます。 Parcelableの実装方法はこちらが非常に参考になります。
Y.A.M の 雑記帳: Android Parcelable を使ってクラスのメンバを一時保存

問題はParcelableを実装したいクラスが抽象クラスだった場合です。Parcelable実装にはParcelable.Createorというスタティックフィールドが必要になりますが、そのフィールドを初期化する際にParcelに保存したデータを復元するためのコンストラクタを呼びます。しかしながら抽象クラスだと当然コンストラクタを呼ぶことができません。以下一部コード例

// Content.java(ContentはParcelableをimplementsしたabstractクラス)
public static final Creator<Content> CREATOR = new Creator<Content>(){
        @Override
        public Content createFromParcel(Parcel parcel) {
            return new Content(parcel); // ここでエラーになります
        }

        @Override
        public Content[] newArray(int i) {
            return new Content[0];
        }
    };

private Content(Parcel in) {} // 実際はこのコンストラクタ内でParcelからデータを読み出します

前置きが長くなりましたがではどうすればよいかというと、独自クラスにSerializableを実装するだけです。
Serializableはメソッドなどをオーバーライドする必要はなくimplementsするだけで大丈夫ですが、クラスの構造がSerialize出来るようになっていないといけません。 Serializableについてはこちらが参考になりますので読んでみてください。

Android SDKの,ParcelableとSerializableの違いを比較 - Intentで独自オブジェクトを運搬する際,役立つのはどちら? - 主に言語とシステム開発に関して
難解なSerializableという仕様について俺が知っていること、というか俺の理解 - 都元ダイスケ IT-PRESS

Serializableなクラスとして実装しておけばbundle.putSerializable(key, val);の形でBundleに格納できます。