I/Oセッション
ViewModel
このようなカウントするLiveDataがあります。
class MainViewModel : ViewModel() { val counter = MutableLiveData(0) }
押したら1増やします。
ViewModelを使用すれば画面回転を乗り越えられます。
当たり前ですが、プロセスキルまでは乗り越えることができません。
いままではこの様なコードを書く必要がありました。
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) viewModel.counter.value?.also { outState.putInt("counter", it) } } override fun onRestoreInstanceState(savedInstanceState: Bundle?) { super.onRestoreInstanceState(savedInstanceState) savedInstanceState ?: return viewModel.counter.value = savedInstanceState.getInt("counter") }
それを楽にするのがSavedStateHandleです。
SavedStateHandle
dependencies
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha01"
LiveData
LiveDataを以下のように書き換えます。
コンストラクタにSavedStateHandleを指定します。
keyを引数にしてLiveDataを取得します。
SavedStateHandleはKey-Valueオブジェクトのようになっています。
class MainViewModel( handle: SavedStateHandle ) : ViewModel() { val counter: MutableLiveData<Int> = handle.getLiveData("counter") }
Activity Fragment
ViewModelを取得する部分にKTXができましたので使います。
implementation "androidx.activity:activity-ktx:1.0.0-alpha08" implementation "androidx.fragment:fragment-ktx:1.1.0-alpha09"
ViewModelを取得します専用のViewModelFactoryがあるのでそれを使います。
このSavedStateVMFactoryは第一引数にApplicationを指定すると解決してくれます。これでAndroidViewModelも使えます。
private val viewModel by viewModels<MainViewModel> () { SavedStateVMFactory(this) }
自分でViewModelFactoryを作りたい場合はAbstractSavedStateVMFactoryを継承してください。
初期値
初期値を指定する場合、以下のようにBundleに入れてあげます。
private val viewModel by viewModels<MainViewModel> { SavedStateVMFactory(this, Bundle().apply { putInt("counter", 0) }) }
おわり
SavedStateHandleを使用するとプロセスキルを乗り越えられるViewModelを作成することができます。
結局はonSaveInstanceStateを使用しているので大きいデータは保存することができないのが注意です。idなどを保存してDBから取得するようにしましょう。