ViewModel
を使うことで画面回転等のConfigurationが変更されたときもデータを保持することが可能になりました。しかし、OSからプロセスKillされてActivityの再生成に対応できません。
この場合は onSaveInstanceState
を使うことで対応することになります。
ほとんどケースでUIの状態はViewModelと多いので、このあたりもViewModelのほうで対応できたらだいぶ楽になると思います。
これを SavedStateHandle
というのを使って保存と取得を行えるようになりました。
まだalpha01なので今後変更はあるかもしれませんが。
環境
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha01'
実装
ViewModel定義
ViewModel自体はコンストラクタに SavedStateHandle
もらうようにするだけです。
ViewModel生成
普通のViewModelの生成と変わらないのですが、Factoryに SavedStateVMFactory
を使います。
これだけで準備完了です。
データを保存と取得
保存と取得は非常に簡単で、 SavedStateHandle
を上記のように使うだけです。これでプロセスがKillされてもsetした値はActivity再生成後も取得できます。
LiveDataを保存と取得
SavedStateHandle
は更にLiveDataに対応しています。
getLiveData
を使うことでLiveDataとして取得することが可能です。更に値をsetしたときにはsetValueと同じで、observeへ通知がいきます。
注意: コードを見る限りLiveData#setValueを使ってるのでBackgroudスレッド等からは呼び出さないようしてください。
扱えるデータ型
Bundle
に保存できるものと同じです。
おまけ: Daggerを使う場合
Daggerを使う場合はいつものようなViewModelFactoryが使えません。ちょっと別のアプローチが必要です。
例えば、次のようにViewModleにRepositoryを渡したい場合です。
この場合はViewModelごとにFactoryを作る必要があります。以下のような感じです。
AbstractSavedStateVMFactory
を継承したFactoryを作ります。このコンストラクタには、 SavedStateRegistryOwner
が必要なります。これはActivityとFragmentが実装してるので、それを渡せば大丈夫です。
Moduleでその SavedStateRegistryOwner
を解決できるようにしてあげます。
実際は他にも色々必要ですが、最終的にActivityはこんな感じになります。