SavedState ViewModelを使ってデータを保持する

Kenji Abe
4 min readMar 16, 2019

--

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はこんな感じになります。

参考

--

--

Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO