2013年3月6日水曜日

Android Parcelable の実装でつまづいたときのメモ

Android の Parcelable の実装でつまづいたので、メモ。

画面が回転したときに表示していた内容が消えてしまわないよう、独自オブジェクトで Parcelable インタフェースを実装し、
  • Activity#onSaveInstanceState(Bundle) で Bundle#putParcelable で書き出す
  • Activity#onRestoreInstanceState(Bundle) で Bundle#getParcelable で読み込む
という処理を行っていました。

つまづいたのは以下の2箇所です。
  1. Parcelable を実装したクラスに CREATOR フィールドを持たせていなかった。
  2. Parcel からのString配列読み込みに Parcel#readStringArray(String[]) を使っていた。

1つ目は、単に、決まりごとを守れていなかったっていうだけでした。
例外はこんな感じです。
android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class ...

http://developer.android.com/reference/android/os/Parcelable.html
には Parcelable を実装したクラスには CREATOR フィールドを持たせろと書いてありましたが、知らなかったので書いていませんでした。書かなくてもコンパイルは通るし、画面回転では問題が起きず、特定の機種でのみ他のアプリ呼出し後に問題が起きる(メモリの状態によって Activity#onRestoreInstanceState が呼ばれたり呼ばれなかったりするためか?)といった感じだったので、問題に気付くのに遅れました。

2つ目は、Parcelable を実装したオブジェクトで空の配列を扱う可能性がある場合は気をつけなければいけないところみたいですね。 例外は、Parcel#readStringArray(String[]) を実行したときの NullPointerException です。ここのページを見て知りましたが、readStringArray では配列が空の場合に例外がスローされてしまうようです。そのため、代わりに createStringArray というのを使うことで解決。String 以外の配列も同様だと思います。

でも
http://developer.android.com/reference/android/os/Parcel.html
を見ても、そんなことは書かれていないような…。

0 件のコメント:

コメントを投稿