1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack ComposeのrememberSaveableはどこまで状態を保持できるのか?rememberとの違いを検証

1
Posted at

はじめに

Jetpack Composeでは、Composable内で状態を保持するためにrememberを使用することがあります。

しかし、画面回転などでActivityが再生成された場合、rememberで保持していた値は失われます。

そのような場合に利用されるのがrememberSaveableです。

rememberSaveableを使うことで画面回転後も状態を復元できますが、

  • rememberとの違いは何か
  • どのタイミングまで状態を保持できるのか
  • アプリを強制終了した場合はどうなるのか

について、実際に検証して確認してみます。

動作確認環境

  • Kotlin 2.4.0
  • Jetpack Compose
  • Material3
  • Android Studio

検証アプリ

今回は以下のようなシンプルな検証画面を作成しました。

rememberrememberSaveableそれぞれで、

  • カウント値
  • TextFieldの入力値

を保持します。

画面回転やアプリの強制停止後に、どのような違いがあるか確認します。

1 初期状態.png

サンプルコード

今回作成した検証アプリのソースコードはGitHubで公開しています。

実装

rememberの場合

rememberを利用して状態を保持します。

var count by remember {
    mutableIntStateOf(0)
}

var text by remember {
    mutableStateOf("")
}

rememberSaveableの場合

rememberSaveableを利用して状態を保持します。

var count by rememberSaveable {
    mutableIntStateOf(0)
}

var text by rememberSaveable {
    mutableStateOf("")
}

今回の検証コードでは、同じUIに対して保持方法だけを変更し、挙動の違いを確認できるようにしています。

検証1:画面回転

まず、両方の項目に値を入力します。

2 値入力.png

その状態で端末を回転させます。

結果

状態保持方法 画面回転後
remember 状態が初期化される
rememberSaveable 状態が復元される

3 画面回転.png

※比較しやすいように、結果確認時は縦向き表示に戻しています。

rememberの場合、画面回転によってActivityが再生成されるため、保持していた状態は失われました。

一方、rememberSaveableの場合は状態が復元されています。

なぜrememberSaveableは復元できるのか

rememberはComposition内で値を保持します。
そのためComposableがCompositionから破棄されると、保持していた状態も失われます。

一方、rememberSaveableは、Composable内の状態を保存可能な形式で管理し、
AndroidのActivity状態保存機構と連携します。

画面回転などでActivityが再生成される際に、保存された状態を取得して復元します。

状態保存の流れを簡単に表すと以下のようになります。

rememberSaveable
        |
        v
Composeの保存機構
        |
        v
Activityの状態保存機構
        |
        v
SavedInstanceState(Bundle)
        |
        v
Activity再生成時に復元

ただし、これは永続保存ではありません。

検証2:adbによる強制停止

次に、adbによる強制停止をした場合の挙動を確認します。

以下の手順でアプリを強制停止します。

  1. 値を入力した状態でアプリを起動したままにする
  2. adbコマンドを利用して強制終了する
  3. アプリを再度起動する

4 値入力.png

結果

状態保持方法 adbによる強制停止後
remember 状態が初期化される
rememberSaveable 状態が初期化される

5 プロセス終了.png

画面回転では復元できたrememberSaveableですが、今回はadb shell am force-stopによる強制停止を行ったため、Activityの状態保存情報が利用されず、rememberSaveableで保持していた状態も復元されませんでした。

rememberSaveableはActivityの状態保存機構を利用する仕組みであり、アプリの永続データを保存するものではありません。

rememberSaveableは永続保存ではない

今回の結果から、

状態保持方法 特徴
remember Compositionが存在する間だけ状態を保持する。Activity再生成では失われる
rememberSaveable SavedStateを利用してActivity再生成後も復元できる。永続保存の仕組みではない

という違いが分かります。

ユーザー設定やログイン情報など、アプリを終了しても保持したいデータはDataStoreやデータベースなど、別の永続化手段を利用する必要があります。

実際のアプリ開発での使い分け

rememberrememberSaveableは、どちらを使うべきかではなく、どの期間データを保持したいかによって使い分けることが重要です。

例えば、以下のような基準で判断できます。

保持したいデータ 適した方法
Composable内だけで利用する一時的なUI状態 remember
画面回転後も維持したい入力値やUI状態 rememberSaveable
アプリ終了後も保持したいユーザー設定 DataStore
大量データや構造化されたデータ Roomなどのデータベース
複数画面で共有する状態 ViewModel + 保存機構

例えば、フォーム入力中の文字列や選択状態などは、画面回転によって失われるとユーザー体験を損なうため、rememberSaveableが適しています。

一方で、ログイン情報やユーザー設定など、アプリを再起動しても必要なデータはrememberSaveableではなく、永続化ストレージを利用する必要があります。

状態を保持する際は「どこまで復元したいのか」「そのデータの寿命はどの程度なのか」を考え、適切な保存方法を選択することが大切です。

まとめ

今回はrememberrememberSaveableの違いを、実際に検証アプリを作成して確認しました。

結果をまとめると以下の通りです。

状態保持方法 再コンポーズ Activity再生成 adbによる強制停止後
remember × ×
rememberSaveable ×

※今回の検証ではadbコマンドによる強制停止を行ったため、rememberSaveableも復元されませんでした。

ただし、OSによるメモリ解放目的のプロセス終了などではActivityの状態保存情報が利用される場合があり、復元される可能性があります。

rememberSaveableは画面回転などによるActivity再生成からUI状態を復元するための仕組みであり、永続保存の代替ではありません。

UI状態、一時的な入力状態、永続化が必要なデータなど、
保持したい期間に応じて適切な保存方法を選択することが重要だと分かりました。

実装時に意識したこと

今回の検証では、状態保持方法以外の条件を揃えるため、同じUIに対してrememberrememberSaveableのみを変更しました。

比較対象以外の差分をなくすことで、それぞれの状態保持の違いを確認できるようにしています。

参考

1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?