Tatsuro のテックブログ

アプリ開発の技術情報を発信します。

【Android × Kotlin】SavedStateHandle を使ってプロセス破棄を越えて値を保持し続ける

今回は、SavedStateHandle を使ってプロセス破棄を越えて値を保持し続ける方法を解説します。

なお、ここに掲載しているソースコードは以下の環境で動作確認しています。

  • Android Studio Bumblebee | 2021.1.1 Patch 3
  • JDK 11.0.11
  • Android Gradle Plugin 7.1.3
  • Kotlin 1.6.20
  • Gradle 7.4.2
  • androidx.lifecycle 2.4.1

SavedStateHandle とは?

以前、ViewModel を使えば、画面回転などにより Activity や Fragment が破棄されても、値を保持し続けることができることを解説しました。

Activity や Fragment が破棄されるだけであれば ViewModel だけで問題ありません。しかし、プロセスが破棄されてしまうと、ViewModel に保持した値も破棄されてしまいます。ViewModel 自体が破棄されてしまうからです。

そこで、ViewModel において、プロセス破棄を越えて値を保持したい場合には SavedStateHandle を使います。

SavedStateHandle には、Key-Value の組み合わせで値を読み書きすることができ、そこに保存された値はプロセス破棄を越えて保持され続けます。

この SavedStateHandle は、ViewModel のコンストラクタの引数から取得することができ、ViewModel の中で SavedStateHandle に対して保持したい値を読み書きします。

class SavedStateViewModel(handle: SavedStateHandle) : ViewModel() {
    ︙
}

また、ViewModel のコンストラクタの引数に SavedStateHandle を持たせる場合、ViewModel のインスタンスの取得方法はいままでのままで大丈夫です。ViewModel のファクトリが ViewModel に対して SavedStateHandle のインスタンスを渡してくれます。

class MainFragment : Fragment(R.layout.main_fragment) {
    private val viewModel: SavedStateViewModel by viewModels()
    ︙
}

ライブラリのインポート

SavedStateHandle を使うためには、以下のようにアプリの build.gradle ファイルの dependencieslifecycle-viewmodel-savedstate を追加すればよいです。

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.1"
}

SavedStateHandle に値を読み書きする

SavedStateHandle に値を読み書きする場合、以下のように SavedStateHandle#getLiveData を使うのが便利です。

class MainViewModel(handle: SavedStateHandle) : ViewModel() {

    /** Button のクリック回数 */
    private val _count = handle.getLiveData("count", 0)
    val count: LiveData<Int> get() = _count

    /** クリック回数をカウントアップする。 */
    fun countUp() {
        val value = count.value!!
        _count.value = value + 1
    }
}

SavedStateHandle#getLiveData は、SavedStateHandle に書き込まれた値を LiveData で受け取ることができるため、値の変更を補足しやすいです。また、MutableLiveData の setValue や postValue に値を設定すると、自動的に SavedStateHandle に値が書き込まれます。

その他

SavedStateHandle には、getLiveData 以外に以下のメソッドが存在します。

メソッド 機能
get 指定されたキーの値を返す。
set 指定されたキーと値の組み合わせで SavedStateHandle に保存する。
contains 指定されたキーの値の有無を返す。
remove 指定されたキーの値を削除する。
keys SavedStateHandle 内に含まれるすべてのキーを返す。

参考

ViewModel の保存済み状態のモジュール

関連記事

ViewModel の使用方法については、以下で解説しています。

tatsurotech.hatenablog.com

LiveData の使用方法については、以下で解説しています。

tatsurotech.hatenablog.com