Androidアプリケーション開発-onSaveInstanceStateメソッドはいつ呼び出されますか?


onSaveInstanceStateメソッドから転載するといつ呼び出されますか?(転載/整理)
  • は、Activityが破棄される前に各インスタンスの状態を保存するために呼び出され、onCreate(Bundle)またはonRestoreInstanceState(Bundle)から状態が回復することを保証することができる.このメソッドは、Activityが破棄される可能性がある前に呼び出され、Activityが将来のある時点で再開されると、その前の状態を回復することができる.たとえば、Activity Bが有効になってActivity Aの先頭にある場合、ある時点でActivity Aがシステム回収のために破棄される場合、Activity AはonSaveInstanceState()によってユーザインタフェースの状態を保存する機会があり、将来ユーザがActivity Aに戻ったときにonCreate(Bundle)またはonRestoreInstanceState(Bundle)によってインタフェースの状態を回復することができる.このメソッドは、onPause()やonStop()のようなActivityライフサイクルのコールバックと混同しないでください.onPause()は、Activityがバックグラウンドに置かれたり、自分で破棄されたりしたときに呼び出され、onStop()はActivityが破棄されたときに呼び出されます.onPause()とonStop()が呼び出されますが、onSaveInstanceState()はトリガーされません.たとえば、ユーザーがActivity BからActivity Aに戻ると、BのonSaveInstanceState(Bundle)メソッドを呼び出す必要はありません.この場合、Bインスタンスはリカバリされません.このシステムは呼び出さないためです.onPause()を呼び出すがonSaveInstanceState(Bundle)を呼び出さない方法の例は、Activity Bが起動した後にActivity Aのフロントエンドにある場合です.Bのライフサイクル全体でAのユーザインタフェース状態が破壊されなければ、システムはActivity Aを呼び出さないonSaveInstanceState(Bundle)方法です.デフォルトのインプリメンテーションは、UIレイヤ上のidを持つviewごとにonSaveInstanceState()メソッドを呼び出し、現在フォーカスされているviewのidを保存します(すべての保存されたステータス情報はデフォルトのonRestoreInstanceState(Bundle)インプリメンテーションで復元されます).この方法を上書きして、各viewに保存されていない追加の情報を保存する場合は、デフォルトの実装中に各ビューのすべてのステータスを呼び出したり、自分で保存したりしたい場合があります.呼び出されると、このメソッドはonStop()の前にトリガーされますが、onPause()の前または後にトリガーされるかどうかは保証されません.
  • ActivityのonSaveInstanceState()メソッドとonRestoreInstanceState()メソッドはライフサイクルメソッドではありません.onCreate()、onPause()などのライフサイクルメソッドとは異なり、必ずしもトリガーされるわけではありません.アプリケーションが予期せぬ状況(メモリ不足、ユーザーが直接ホームキーを押すなど)に遭遇し、システムによってActivityが破棄されると、onSaveInstanceState()メソッドが呼び出されます.しかし、ユーザーがアクティブにActivityを破棄すると、たとえばアプリケーションで戻りキーを押すと、onSaveInstanceState()メソッドは呼び出されません.この場合,ユーザの行動がActivityを保存する必要がない状態を決定するためである.通常、onSaveInstanceState()メソッドは一時的な状態を保存するのにのみ適しており、onPause()メソッドはデータの永続化保存に適しています.また、画面の方向が変更されると、Activityは破棄され、再作成されます.Activityが破棄される前にデータをキャッシュし、Activityが再作成された後にキャッシュされたデータを復元したい場合は、ActivityのonSaveInstanceState()メソッドとonRestoreInstanceState()メソッドは、次のように書き換えることができます.
    public class PreferencesActivity extends Activity {
      private String name;
      protected void onRestoreInstanceState(Bundle savedInstanceState) {
          //  
          name = savedInstanceState.getString("name");
          super.onRestoreInstanceState(savedInstanceState);
      }
      protected void onSaveInstanceState(Bundle outState) {
          //  
          outState.putString("name", "l_yqing");
          super.onSaveInstanceState(outState);
      }
    } 
  • ユーザーが新しいActivityを起動した後、以前のActivityがメモリ内で停止している可能性もあるし、新しいActivityがより多くのメモリを必要としているためシステムによって破棄された可能性もあるが、いずれにしても、ユーザーが新しいActivityで戻るキーをクリックしたとき、彼が望んでいたのは元のActivityのインタフェースである.元のActivityが再作成された場合、ユーザーが最後に見たときの姿に戻ります.どうすればいいのでしょうか.実は難しくなく、onPause()やonStop()やonDestroy()に必要なデータを保存すればいいのです.しかし、Googleは今また新しいものを出しています:onSaveInstanceState()は、その名を見てその意味を知っています:それはインスタンスの状態を保存するために使用されています.この「インスタンス」はActivityオブジェクトではなく、Activityの破棄はそのプロセスが殺されたためです.onSaveInstanceState()は、Activityを破棄する必要があるとシステムが感じたときに呼び出され、パラメータBundleに渡されます.このBundleはMap辞書のようなものと考えられ、「キー値」の形式でデータを保存します.今また卵が痛くなった:onPause()にデータを保存できるのではないでしょうか.どうしてまたこんなやつを作ったの?それらの間にはどんな関係がありますか?従来,onSaveInstanceState()メソッドの主な目的はActivityの状態に関するデータを保存することであり,システムがActivityを破棄する際にActivityが次に現れる様子が以前と全く同じであることを望むとonSaveInstanceState()を呼び出し,そうでないと呼び出さない.この点を理解するには、onSaveInstanceState()メソッドは常に呼び出されるわけではありません.たとえば、ユーザーがActivityで戻るキーをクリックすると、呼び出されません.ユーザーはこのActivityが破棄されることを明確に知っているので、次の姿が今と同じようになることを望んでいません(もちろん、開発者は死ぬ時の表情を保つことができますが、あなたがそうしなければならないので、システムも仕方がありません).onSaveInstancesState()を呼び出す必要はありません.onPause()、onStop()およびonDestroy()に保存する必要があるのは、状態を復元するためのデータではなく、永続化する必要があるデータであり、状態データにはonSaveInstanceState()という専門的な方法があることがわかります.データはBundleに保存され、Bundleはシステムによって永続化されます.ActivityのonCreate()を再び呼び出すと、元の保存されていたBundleが転送され、前回の臨死時の姿を復元し、前回破棄されたときにBundleが保存されなかった場合はnullとなる.まだ終わっていませんが、自分のonSaveInstancesState()を実現していない場合は、Activity上のコントロールの様子が保存され、復元される可能性があります.ActivityクラスではonSaveInstanceState()が実装されていたが、onSaveInstanceState()のデフォルト実装では、EditTextに入力された文字やCheckBoxが選択されているかどうかなど、すべてのコントロールに関するメソッドが呼び出され、コントロールの状態が保存される.しかし、すべてのコントロールが保存できるわけではありません.これは、layoutファイルでコントロールに名前(android:id)を付けたかどうかによって異なります.有名なものは保存し、無名のものは放っておく.既成品がある以上、私たちは果たして自分でonSaveInstanceState()方法を実現しないのだろうか.これは状況によって異なります.もしあなたの派生クラスに変数がUIに影響したり、プログラムの動作に影響したりしたら、もちろんこの変数も保存しなければなりません.そうしないと、自分で実現する必要があります.そうしないと、必要ありませんが、多くの場合、自分で実現する必要があります.ところで、あなたのインプリメンテーションで親のonSaveInstanceState()メソッドを呼び出すのを忘れないでください.注意:onSaveInstanceState()メソッドは、破棄されるたびに呼び出されるわけではありませんので、永続化が必要なデータは保存しないでください.onPause()メソッドで保存するのが最適です.

  • heiguyのコラムonSaveInstanceStateとonRestoreInstanceStateからトリガーされるタイミング
    まずApplication Fundamentalsの話を見てみましょう.
    Android calls onSaveInstanceState()before the activity becomes vulnerable to being destroyed by the system,but does not bother calling it when the instance is actually being destroyed by a user action(such as pressing the BACK key)この言葉から分かるように、あるactivityが「容易」にシステムに破棄されると、このactivityのonSaveInstanceStateが実行され、例えばユーザがBACKキーを押すと、activityがユーザによって自発的に破棄されない限り.上の二重引用符に注意してください.「簡単」とは何ですか.このactivityはまだ破棄されておらず、可能性にすぎないという意味だ.この可能性はどれらがありますか?onSaveInstanceStateメソッドとonRestoreInstanceStateメソッドを含むactivityのすべてのライフサイクルのonXXXメソッドを書き換えることで、現在のtaskの最上位にactivity(activity Aと仮定)が表示されている場合、
    そのonSaveInstanceStateメソッドがいつ実行されるかについては、次のような状況があります.
  • ユーザがHOMEキーを押すと.これは明らかで、システムはあなたがHOMEを押した後にどれだけ他のプログラムを実行するかを知らないで、もちろんactivity Aが破棄されるかどうか分からないので、システムはonSaveInstancesStateを呼び出して、ユーザーにいくつかの非永久的なデータを保存する機会を与えます.以下のいくつかの状況の分析はすべてこの原則
  • に従う.
  • HOMEキーを長押しし、他のプログラムを実行する場合を選択します.
  • 電源ボタン(画面表示をOFF)を押した場合.
  • activity Aから新しいactivityが起動されたとき.
  • 画面方向切り替えの場合、例えば縦から横に切り替えた場合.

  • 画面が切り替わる前に、システムはactivity Aを破棄し、画面が切り替わると自動的にactivity Aを作成するので、onSaveInstanceStateは必ず実行されます.要するに、onSaveInstanceStateの呼び出しは重要な原則に従います.つまり、システムが「許可されていない」ときにactivityを破棄すると、onSaveInstanceStateはシステムに呼び出されます.これはシステムの責任です.データを保存する機会を提供しなければならないからです(もちろん保存しないなら勝手にしてください).
    onRestoreInstanceStateメソッドについては、onSaveInstanceStateメソッドとonRestoreInstanceStateメソッドの「必ずしも」がペアで呼び出されるとは限らず、onRestoreInstanceStateが呼び出される前提は、activity Aが「確かに」システムによって破棄されることであり、このような可能性がある場合にのみ、このメソッドは呼び出されず、例えばactivity Aが表示されている場合、ユーザがHOMEキーを押してメインインタフェースに戻り、その後ユーザがactivity Aに戻る場合、activity Aはメモリの原因でシステムによって破棄されることはないので、activity AのonRestoreInstancesStateメソッドは実行されません.
    また、onRestoreInstanceStateのbundleパラメータもonCreateメソッドに渡され、onCreateメソッドでデータ復元を選択することもできます.