今回は、AndroidのSavedStateHandleを解説します。
SavedStateHandle
クラスは、set()
メソッドおよび get()
メソッドを介して、SavedState
との間でデータの書き込みや取得を行えるようにする Key-Value マップです。また、getLiveData()
を使用して LiveData
オブザーバブルにラップされている値を SavedStateHandle
から取得できます。キーの値が更新されると、LiveData
が新しい値を受け取ります。
build.gradle
の dependencies
では、以下を必要とします。
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
使用例
例えば、以下のように使用します。
class MainViewModel( // ViewModelの第1引数にSavedStateHandleを指定します。 private val handle: SavedStateHandle ) : ViewModel() { companion object { // 値の出し入れに使用するキーを定数宣言します。 private const val KEY_COUNT = "count" } // SavedStateHandleからキーKEY_COUNTにひも付くMutableLiveDataを探して取り出します。 // 存在しない場合は新しく作ります。 // そして、SavedStateHandle内でキーKEY_COUNTに対してひも付けます。 // 初期値0。 private val _count = handle.getLiveData(KEY_COUNT, 0) val count: LiveData<Int> get() = _count fun countUp() { // _count.valueはInt?型ですが、SavedStateHandle#getLiveData呼び出し時に初期値を設定しており、 // nullが入り込むことがありません。よって、!!によって強制的にアンラップしています。 val currentCount = _count.value!! // SavedStateHandle#getLiveDataにて値を取り出している場合、 // SavedStateHandle#setで値の格納と同時に監視者への更新通知が行われます。 // なお、SavedStateHandle#getにて値を取り出している場合には、 // 監視者への更新通知が行われません。 // また、内部的にはMutableLiveData#setValueが呼ばれているため、 // ワーカースレッドから呼び出してはいけません。 handle.set(KEY_COUNT, currentCount + 1) }
また、ViewModel
の取得でby viewModels()
を使用している場合、viewModels()
が ViewModel
に SavedStateHandle
のインスタンスを渡しているため、コードを変更する必要はありません。
class MainFragment : Fragment(R.layout.main_fragment) { private val viewModel: MainViewModel by viewModels()