読者です 読者をやめる 読者になる 読者になる

プログラマってこんなかんじ??

アプリ作ったり歌ったりしてます

Activity再生成時のデータの保存・復元(Fragment#setRetainInstance)

Android
  1. ネットワークからデータ取得(画像とか)
  2. データ取得完了したら画面にデータ反映


こういうパターンってよくありますよね。このときに画面回転等のコンフィグ変更(縦横切替とか)が行われると 「Activity のインスタンスが破棄->再生成」 されるので、何も考えてないと保存データも一緒に破棄されてしまいます。なので、内部に保存しているデータを 「保存/復元」 する必要があります。


自分、コンフィグ変更で Activity再生成 とかされると正直めんどくさいので、基本的に "android:configChanges" の属性指定で Activity再生成抑止 して データの保存/復元 とか考えない方向でいいんじゃね。とか思ってたんです(すみません)。


でもよくよく調べてたら Activity再生成 を回避できないケース がありまして。例えば、「フォント切替」。


こいつは configChanges のパラメータにないので、厳密にいうとやっぱり Activity再生成 は避けて通れない。悲しいです。というわけで、Activity再生成時の内部データの保存/復元方法 はどうやるのが正解なのだろう、と調べてみると 2.x、3.x〜系 でだいぶ変わっていました。自分への備忘録の意味も込めてまとめてみます。


Activity再生成時の保存/復元処理

2.x系(API Level 10まで)
  • サイズ小さめのデータの場合(serializeされる)
    • Activity#onSaveInstanceState で保存処理
    • Activity#onCreate、onRestoreInstanceState で復元処理
  • サイズ大きめのデータの場合(serializeされない)
    • Activity#onRetainNonConfigurationInstance で保存処理
    • 再生成後に任意のタイミングで Activity#getLastNonConfigurationInstance 呼び出して復元処理
3.x、4.x系(API Level 11〜)
  • サイズ小さめのデータの場合(serializeされる) ※Activity単位(2.x系と一緒)
    • Activity#onSaveInstanceState で保存処理
    • Activity#onCreate、onRestoreInstanceState で復元処理
  • サイズ小さめのデータの場合(serializeされる) ※Fragment単位
    • Fragment#onSaveInstanceState で保存処理
    • Fragment#onCreate で復元処理
  • サイズ大きめのデータの場合
    • Fragment#setRetainInstance(true) を指定して Fragment が破棄されないようにし、そこへデータ保存
    • 任意のタイミングで↑の Fragment からデータ取得して復元処理

サイズ小さめデータの 保存/復元 を行う際、Activity#onSaveInstanceState〜 については 2.x系 と特に変わらないのですが、Fragment単位でも同様のことができるようになってます。


サイズ大きめデータの 保存/復元 を行う際、3.x系〜は Activity#onRetainNonConfigurationInstance が非推奨になってます。代わりに Fragment#setRetainInstance(true) を使用する方法が推奨されています。


Fragment#setRetainInstance(true) を呼び出すことでどうなるかというと、

  • Activity再生成時に Fragment#onDestroy、onCreate が呼ばれなくなる。
  • Activity再生成時には Fragment#onDetach、onAttach が呼び出されるだけ。
  • Fragmentインスタンス破棄されないので Fragmentインスタンス内にデータをそのまま保持しておくことが可能。

ということみたいです。つまり、でかいデータについては、

Fragmentインスタンス自体を破棄されないようにしとく。
で、Fragmentインスタンス内部でそのまま保持っておく。

ってことですかね!


参考