LoginSignup
1
2

【Android】状態保存はSavedStateHandle.saveableが便利

Posted at

はじめに

AndroidにはActivityが破棄されるタイミングが存在します。
例えば、端末内のメモリーが圧迫されている状態などがそれに該当しますが、開発者設定でActivityを保持しない設定にした場合も同様の状態を再現することが可能です。
Activityが破棄されるとViewの状態はことごとく初期化され、文字を多く入力する画面などで発生すればユーザビリティが大きく低下するような問題が発生します。
その場合の対策としてSaveStateHandleが存在していると思いますが、このSaveStateHandleを便利に使用可能なsaveableを今回ご紹介したいと思います。

使用準備

まずsaveableを使用するためには以下を追加する必要があります。

build.gradle
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"

saveableは2.5.0で追加された機能になりますので、バージョンを指定する際は2.5.0以上を指定してください。

saveable使用例

ライブラリを追加したらsaveableを使用可能な状態となります。
まず、saveableを使用しない場合のSaveStateHadleの実装例になります。

SavedStateViewModel.kt
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    val filteredData: LiveData<List<String>> =
        savedStateHandle.getLiveData<String>("query").switchMap { query ->
        repository.getFilteredData(query)
    }

    fun setQuery(query: String) {
        savedStateHandle["query"] = query
    }
}

これまでは上記のような形でKeyを指定し、状態を保持しています。
保持する情報が多ければ多いほどこのKeyの管理が煩わしいと感じるケースは少なくないと思います。

そこで、saveableの実装例は以下になります。

SavedStateViewModel.kt
class SavedStateViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {

    val filteredData: List<String> by savedStateHandle.saveable {
        mutableStateOf>(emptyList())
    }

    fun setQuery(query: String) {
        withMutableSnapshot {
            filteredData = query
        }
    }
}

saveableを使用しない場合と比べ、煩わしいと感じていたKeyの指定がなくなり、値の保持に関する設定もシンプルになっています。
これまでの実装と比べ、直感的な実装で値を保持できるようになります。

ただし一点注意点として、2.5.0で追加されたばかりの機能なので現段階ではexperimentalな機能となります。
今後のこの機能に改修が入り、想定と違った動作をする場合がありますのでその点ご注意ください。

さいごに

そろそろJetpack Composeの記事も上げていきたいところですね。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2