Activityのステータスデータの保存と復元

3314 ワード

一般に、onPause()およびonStop()メソッドを呼び出すactivityインスタンスはメモリに存在し、activityのすべての情報およびステータスデータは消失せず、activityがフロントに戻るとすべての変更が保持される. 
ただし、システムのメモリが不足すると、onPause()とonStop()メソッドを呼び出すactivityがシステムによって破棄される可能性があり、このときメモリにはそのactivityのインスタンスオブジェクトが存在しない.その後このactivityが再びフロントに戻ると、前の変更は消えてしまいます.これを回避するために、開発者はonSaveInstanceState()メソッドを上書きすることができる.onSaveInstanceState()メソッドはBundleタイプのパラメータを受け入れ、開発者はステータスデータをこのBundleオブジェクトに格納することができる.これにより、activityがシステムによって破壊されても、ユーザーがこのactivityを再起動してそのonCreate()メソッドを呼び出すと、上記のBundleオブジェクトは実パラメータとしてonCreate()メソッドに渡され、開発者はBundleオブジェクトから保存されたデータを取り出すことができる.そしてこれらのデータを利用するactivityを破壊される前の状態に戻す.
public class MainActivity extends Activity {  
    public static final int SECOND_ACTIVITY = 0;  
    private String temp;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        //  savedInstanceState ,  savedInstanceState null  
        if (savedInstanceState != null) {  
            temp = savedInstanceState.getString("temp");  
            System.out.println("onCreate: temp = " + temp);  
        }  
    }  
  
    public void onResume() {  
        super.onResume();  
        temp = "xing";  
        System.out.println("onResume: temp = " + temp);  
        //  activity   
        if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {  
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
            System.out.println(" ");  
        }  
    }  
      
    //  outState ,  activity onCreate   
    @Override  
    protected void onSaveInstanceState(Bundle outState) {  
        super.onSaveInstanceState(outState);  
        outState.putString("temp", temp);  
    }  
}

なお、onSaveInstanceState()メソッドは、ステータスデータを保存する必要がないシーンがあるため、必ずしも呼び出されるわけではない.例えば、ユーザがBACKキーを押すactivityを終了すると、ユーザは明らかにこのactivityを閉じたいと思っているが、この場合、次回のリカバリのためにデータを保存する必要はない、すなわちonSaveInstancesState()メソッドは呼び出されない.onSaveInstanceState()メソッドを呼び出すと、onPause()メソッドまたはonStop()メソッドの前に呼び出されます. 
onSaveInstanceState()メソッドのデフォルト実装
開発者がonSaveInstanceState()メソッドを上書きしていない場合、このメソッドのデフォルトインプリメンテーションは、activity内の様々なUIコントロールの状態など、activity内のいくつかの状態データを自動的に保存する.Androidアプリケーションフレームワークで定義UIコントロールのほとんどは、onSaveInstanceState()メソッドを適切に実現しているため、activityが破壊され再構築すると、これらのUIコントロールは状態データを自動的に保存して復元する.例えば、EditTextコントロールは入力データを自動的に保存して復元し、CheckBoxコントロールは選択状態を自動的に保存して復元する.開発者は、これらのコントロールに一意のIDを指定するだけで(android:id属性を設定すればよい)、残りのことは自動的に完了する.コントロールにIDを指定しないと、このコントロールは自動的なデータ保存や復元操作を行う.
前述のように、開発者がonSaveInstanceState()メソッドを上書きする必要がある場合、一般的には、最初の行のコードでこのメソッドのデフォルト実装:superが呼び出される.onSaveInstanceState(outState).
onSaveInstanceState()メソッドを上書きする必要があるかどうか
このメソッドのデフォルトインプリメンテーションがUIコントロールのステータスデータを自動的に保存できる以上、このメソッドを上書きする必要があるのはいつですか?
追加のデータを保存する必要がある場合は、onSaveInstanceState()メソッドを上書きする必要があります.クラスのメンバー変数の値を保存する必要がある場合(前例参照).
onSaveInstanceState()メソッドはどのデータを保存するのに適していますか?
onSaveInstanceState()メソッドは必ずしも呼び出されるとは限らないため、データベースへのレコードの挿入など、永続化データの保存には不向きである.永続化データを保存する操作はonPause()に置くべきである.onSaveInstanceState()メソッドは、UIコントロールの状態、メンバー変数の値などの過渡データを保存するのにのみ適する.
Activityの破壊と再構築を引き起こす他の状況
システムがメモリ不足の原因でactivityが破壊されるほか、一部のシステム設定の変更によりactivityが破壊され、再構築されることもある.例えば、画面方向の変更(前例参照)、機器の言語設定の変更、キーボードのイジェクト等がある.