前回の続き

いろいろ説明しましたが、結局どのようにプログラミングすればよいのかをまとめたいと思います。

アプリケーション全体の状態管理について

  • アプリがバックグラウンドになったら、いつProcessがメモリから消えるかわからない
  • よってメモリ上だけでアプリケーションの状態を管理させてはならない
  • アプリケーションの状態を管理したい時は、Shared PreferenceかContent Providerを使って状態を保存する
  • Applicationクラスを継承してクラスを作り、そのonCreateが呼ばれた時が、Processが生成・再生成されるタイミングで、ここでstatic変数やSystemプロパティの初期化、および前回の状態復帰を行う
  • static変数でメモリ上だけで管理して良いのは、Process復帰後、空に戻っても良いキャッシュデータなどに限る

Activityごとの状態管理について

  • Activityがバックグラウンドになったら、いつメモリから消えるかわからない
  • よってActivityのstatic変数を定義しメモリ上だけで状態管理してはならない
  • Activityの状態の保存はonSaveInstanceStateで行い、onCreateで復帰するのが定石
  • メモリから消えたProcessが復帰された時、メモリに復帰するActiivtyは以前に開いていたもののみ。復帰したActivityのstatic initalizerは呼ばれるが、他のActivityのstatic initializerは呼ばれないことに注意
  • 最初に起動されるActivityクラスのstatic initializerを使ってアプリの初期化処理を行なってはいけない。Systemプロパティの初期化を行なってはならない。これらはApplication#onCreateで行うほうがよい

複雑な画面表示を完全に復帰することは難しいです。

ちなみに現行のfacebookアプリは以下の様な動作をします。

  • ニュースフィードを開く
  • バックグラウンドにして一晩おく
  • 再び開く
  • 前回の状態から復帰せず、再び最初から読み込み表示する

このようにActivityを開いた状態に戻るという処理をしているアプリも多いので、そのようにするのも手である。つまり最低限の状態復帰に限り、画面遷移の整合性を崩さないようにだけ注意する。

たとえば前の一覧画面で項目Aを選択して項目Aの詳細をサーバーから取得して表示していたのに、復帰したら画面表示が空だというのはバグである。項目Aを表示していたことはonSaveInstanceStateで行い、onCreateで再び詳細をサーバーから取得して表示するべきだろう。

まとめ

とにかく大事なことは、

  • Process、Activityはバックグランドになったら、いつメモリから消されるかわからないこと
  • Processがメモリから消えることはアプリの終了を意味しないこと
  • アプリの状態は変更のたびに保存して、Processの生成・再生成と共に復帰できるようにすること
  • static変数(シングルトン含む)でメモリ上のみで状態管理しないこと

である。