Android開発シリーズ(1):Activityライフサイクル理解とまとめ2

4740 ワード

一、onSaveInstanceState()の理解


ActivityがユーザがBackボタンをクリックしたため、またはactivityがfinish()を呼び出して自分を終了したため、システムはActivityインスタンスへの参照を失う.この動作は、このactivityを必要としないことを意味するからである.
しかし、システムリソースの緊張によりActivityのDestoryが発生した場合、このActivityにユーザが戻ったときにこのActivityが存在したレコードが存在し、保存されたレコードデータ(ActivityがDestoryになったときの状態を説明する)を使用して新しいActivityインスタンスが再作成されます.システムが以前の状態を復元するために保存したデータは「instance state」と呼ばれ、Bundleオブジェクトに保存されているkey-value pairsです.
Caution:
  • onSaveInstanceStateのコールバックは、ステータス情報を保存するために使用されます.
  • onRestoreInstanceStateのコールバックは、以前に保存したデータを復元するために使用されます.

  • 二、onSaveInstanceStateとonRestoreInstanceStateの呼び出しタイミング


    通常、他のactivityにジャンプしたりホームをクリックしたりすると、現在のactivity実行onSaveInstancesStateが実行されます.この場合のactivityはdestoryによって保存され、その後のリカバリのために状態を保存する必要があるため、ジャンプしたactivityクリックbackから前のactivityに戻ると、ジャンプ前のactivityはスタックを戻す操作であり、この場合onSaveInstanceStateは実行されません.このactivityには再構築が必要な操作は存在しないからです.
  • Backキーが正常に終了しても、onSaveInstanceStateとonRestoreInstanceStateは呼び出されません.
  • D/Activity1﹕ onCreate
    D/Activity1﹕ onStart
    D/Activity1﹕ onResume
    D/Activity1﹕ onPause
    D/Activity1﹕ onStop
    D/Activity1﹕ onDestroy
    
  • Homeキーが終了するとonSaveInstanceStateが呼び出されます.
  • D/Activity1﹕ onCreate
    D/Activity1﹕ onStart
    D/Activity1﹕ onResume
    D/Activity1﹕ onPause
    D/Activity1﹕ onSaveInstanceState
    D/Activity1﹕ onStop
    D/Activity1﹕ onDestroy
    
  • HomeキーリカバリはonRestoreInstanceState()を呼び出します.
  • D/Activity1﹕ onCreate
    D/Activity1﹕ onStart
    D/Activity1﹕ onRestoreInstanceState
    D/Activity1﹕ onResume
    
  • が他のActivityに入るとonSaveInstanceStateが呼び出されます.
  • A-B-A
    D/Activity1﹕ onPause
    D/Activity2﹕ onCreate
    D/Activity1﹕ onSaveInstanceState
    D/Activity1﹕ onStop
    D/Activity1﹕ onRestart
    D/Activity1﹕ onStart
    D/Activity1﹕ onResume
    D/Activity2﹕ onDestroy
    

    Aを返すとonRestoreInstanceStateは呼び出されませんでした.Aはバックグラウンドにいるので殺されていません.
    Caution:呼び出しの鍵はActivityに予期せぬDestroyのリスクがあるかどうかです.

    三、Activity状態の保存


    ActivityがStopを開始すると、onSaveInstanceState()が呼び出され、Activityはキー値ペアのセットでステータス情報を保存できます.この方法では、EditTextコンポーネントのテキストやListViewのスライド位置など、Activityビューのステータス情報がデフォルトで保存されます.Activityに追加のステータス情報を保存するには、onSaveInstanceState()を実装し、Bundleオブジェクトにkey-value pairsを追加する必要があります.たとえば、次のようにします.
    static final String STATE_SCORE = "playerScore";
    static final String STATE_LEVEL = "playerLevel";
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {    
        // Always call the superclass so it can save the view hierarchy state    
        super.onSaveInstanceState(savedInstanceState);   
       
        // Save the user's current game state    
        savedInstanceState.putInt(STATE_SCORE, 1);    
        savedInstanceState.putInt(STATE_LEVEL, 2);
    }
    

    Caution:
  • は、デフォルトの親インプリメンテーションがビューステータスの情報を保存するためにonSaveInstanceState()メソッドの親インプリメンテーションを呼び出す必要があります.
  • Activityビューのステータス情報はデフォルトで保存され、追加のステータス情報を保存する必要がある場合にのみ呼び出されます.

  • 四、Activity状態を回復する


    ActivityがDestoryから再構築されると、システムによって渡されたActivityのBundleから保存された状態を復元できます.
    onCreate()とonRestoreInstanceState()コールバックメソッドは、同じBundleを受信し、同じインスタンスステータス情報が含まれています.
  • onCreate()メソッドは、新しいActivityインスタンスを最初に作成し、再作成する前にDestoryされたインスタンスを再作成するときに呼び出されるため、Bundleオブジェクトを読み込む前にnullであるかどうかを検出する必要があります.nullの場合、システムはリカバリ前にDestoryのActivityではなく、新しいActivityインスタンスを作成します.
  • @Override
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        // Always call the superclass first // Check whether we're recreating a previously destroyed instance 
        if (savedInstanceState != null) { 
            // Restore value of members from saved state 
            mCurrentScore = savedInstanceState.getInt(STATE_SCORE);    
            mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } 
         else { 
            // Probably initialize members with default values for a new instance
         }
         ...
    }
    
  • onCreateメソッドでデータを復元するのではなく、onRestoreInstanceState()を実装することもできます.onRestoreInstanceState()メソッドはonStart()メソッドの後に実行されます.システムは、リカバリが必要なステータス情報がある場合にのみonRestoreInstanceState()を呼び出すため、Bundleがnullであるかどうかを確認する必要はありません.
  • public void onRestoreInstanceState(Bundle savedInstanceState)
     { 
        // Always call the superclass so it can restore the view hierarchy 
        super.onRestoreInstanceState(savedInstanceState); 
        // Restore state members from saved instance 
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE); 
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    }
    

    Caution:上記と同様に、onRestoreInstanceState()メソッドの親インプリメンテーションを呼び出す必要があります.これにより、デフォルトの親インプリメンテーションがビューステータスの情報を保存できます.
    関連記事:Android Training ActivityライフサイクルのonSaveInstanceState
    [2015-08]