onSaveInstanceStateのタイミング

2019年5月13日

onSaveInstanceStateの役割とは?

ActivityやFragmentのライフサイクルを語る上で欠かせないのがonSaveInstanceStateです。

onSaveInstanceStateはBundleクラスを使ってAndroidの判断でActivityやFragmentを

強制的に停止、終了する際の一時的なデータ保存に使用します。

 

onSaveInstanceStateのタイミングは?

onSaveInstanceStateは、onPauseの直後に呼ばれます。

ちなみにonPauseが呼ばれる場面は具体的に以下となります。

  • アプリがユーザに見える状態(フォアグラウンド)から、
    ユーザに見えない状態(バックグラウンド)に遷移した際に、
    アプリで最後に表示していた画面のonPauseが呼ばれる。
  • アプリを終了する際にアプリで最後に表示していた画面のonPauseが呼ばれる。
  • 画面Aから画面Bに遷移する際に、画面AのonPauseが呼ばれる。

従って、上記場面の直後にonSaveInstanceStateが呼ばれます。

 

Bundleの保存場所

Bundleは前述のタイミングでonSaveInstanceStateが呼ばれた後、

アプリのプロセスからSystemServerプロセスのActivityRecordに保存されます。

SystemServerプロセスは前面アプリや永続化プロセスよりも優先度が

高くなっている為、基本的にKillされることはないと考えて大丈夫です。

 

保存・復元するべきデータ

Bundleには下記データを保存・復元すると良いでしょう。

  • ActivityやFragmentの状態変数
  • EditText等のユーザが入力した値の情報

一例をあげますと、皆さんがアプリのユーザだとして、

  1. A画面のポートレイト表示でEditTextに”名前”と入力
  2. A画面を回転させてランドスケープ表示にする
  3. A画面のEditTextを確認する

という手順を踏んだ時に、手順3で”名前”と入っていた方が便利ですよね?

手順3でEditTextに”名前”と表示させるには、手順2実施後のonPause直後に呼ばれるonSaveInstanceStateで

EditTextの入力内容をbundleに保存する処理と、onCreateで画面の初期化を行う際にEditTextにBundleから取得した内容を

復元する処理の実装が必要になります。

 

onSaveInstanceStateのサンプルコード

下記のサンプルではonSaveInstanceStateでデータの保存を行い

onCreateでデータの復帰を行っています。

 

ちなみに、Bundleは標準ではNullが返ってくる仕様になっていますので、

Nullチェックせずにアクセスしますとアプリが落ちますのでご注意ください。

@Override
    public void onCreate(Bundle tBundle){
        super.onCreate( tBundle ) ;
        if( tBundle == null ){
            return ;
        }
  
        //データの復帰
        mBirthDay = tBundle.getString("BirthDay") ;
        mUserName = tBundle.getString("UserName") ;
    }
        
    @Override
    public void onSaveInstanceState( Bundle tBundle ){
        super.onSaveInstanceState( tBundle ) ;
        //データの保存
        tBundle.putString( "BirthDay", mBirthDay ) ;
        tBundle.putString( "UserName", mUserName ) ;
    }

onSaveInstanceStateの注意点

実はonSaveInstanceStateは古いバージョンのOSでは必ず呼ばれる保証がされていません。

詳しくは下記の公式の見解をご覧ください。

 

引用:Android Developers

If called, this method will occur after onStop() for applications targeting platforms starting

with Build.VERSION_CODES.P. For applications targeting earlier platform versions

this method will occur before onStop() and

there are no guarantees about whether it will occur before or after onPause().

 

onSaveInstanceStateが呼び出された場合、

このメソッドは、Build.VERSION_CODES.Pで始まるアプリケーションのonStop()の後に発生します。

以前のプラットフォームのバージョンを対象としたアプリケーションの場合、

このメソッドはonStop()より前に実行され、onPause()の前後で発生するかどうかは保証されません。

 

とはいっても、下記で言っているように2018年現在のAndroidの最新バージョンでは必ずよばれます。

 

以前のプラットフォームのバージョンを対象としたアプリケーションの場合

 

具体的なバージョンは覚えていないのですが、恐らくAndroid5系以降はonSaveInstanceStateは必ず呼ばれていたと思います。

Android5系未満かつ、特定の場面のみonSaveInstanceStateが呼ばれないケースがあると覚えておいてください。

特定の場面が何かを知りたい方はonSaveInstanceStateが呼ばれないのはなぜかの記事をご覧ください。