web-dev-qa-db-ja.com

Android静的オブジェクトのライフサイクル

イベント検索アプリケーションを作成しています。1つの画面から検索条件を設定し、別の画面に入力すると、ユーザーは3番目の画面から検索条件を編集して4番目の画面に移動できます。

上記のタスクを達成するために、アプリケーション周辺の値を記憶する静的オブジェクトを使用しています。特別なことをする必要はありません。

しかし、Androidメモリ不足が検出された場合Android静的オブジェクトの削除???

Androidはマルチタスクをサポートします。ユーザーが別のアプリケーションに切り替え、ユーザーが戻ってきたときにアプリケーションがおかしくなり始めたら、静的タスクはマルチタスク時に削除されますか?シングルトンメソッドを介して静的オブジェクトを保持する方が良い方法ですか?

96
d-man

少し背景を説明しましょう。アプリケーションを起動するとどうなりますか?
OSはプロセスを開始し、それに一意のプロセスIDを割り当て、プロセステーブルを割り当てます。プロセスはDVM(Dalvik VM)のインスタンスを開始します。各アプリケーションはDVM内で実行されます。
DVMは、クラスロードのアンロード、インスタンスのライフサイクル、GCなどを管理します。

静的変数の存続期間:静的変数は、クラスがJVMによってロードされると存在し、クラスがアンロードされると消滅します。

したがって、Androidアプリケーションを作成し、静的変数を初期化すると、次のいずれかが発生するまでJVMに残ります。
1。クラスはアンロードされます
2。 JVMがシャットダウンします
3。プロセスが死ぬ

別のアプリケーションの別のアクティビティに切り替えても静的変数の値は保持され、上記の3つのいずれも発生しないことに注意してください。上記の3つのいずれかが発生した場合、スタティックはその値を失います。

これは、数行のコードでテストできます。

  1. アクティビティのonCreateで初期化されていない静的を出力します-> nullを出力します
  2. 静的を初期化します。印刷->値はnull以外
  3. 戻るボタンを押して、ホーム画面に移動します。注:ホーム画面は別のアクティビティです。
  4. アクティビティを再度起動します->静的変数はnull以外になります
  5. DDMS(デバイスウィンドウの停止ボタン)からアプリケーションプロセスを強制終了します。
  6. アクティビティを再起動します->静的値はnull値になります。

お役に立てば幸いです。

232
Samuh

まあ、Singletonパターンも静的変数の使用に基づいているため、実際には同じ位置にいます。静的アプローチはほとんどの場合に機能しますが、場合によっては、メモリがいっぱいになり、アプリケーションが次の画面に移動する前に別のアクティビティがフォアグラウンドになると、アクティビティのプロセスが強制終了され、静的な値が失われる場合があります。ただし、Androidには、状態間で値を保持するか、次のような値を送信するいくつかのオプションがあります。

  • インテントを使用すると、アクティビティからアクティビティに検索条件を渡すことができます(Web HTTPリクエストと同様)
  • アプリケーションの設定を使用して、値を保存し、それらを必要とするアクティビティで値を取得できます
  • sqliteデータベースを使用すると、テーブルに保存して後で取得できます
  • アクティビティ状態を保存するだけで、再起動時に以前に選択した値がフィールドに入力されるようにする必要がある場合は、onSaveInstanceState()アクティビティメソッドを実装できます。これは、アクティビティの状態の永続化にはお勧めできません。

プリファレンス、インテント、sqliteデータベースの使用例のコード例を入手するには、Googleコードまたは他のオープンソースAndroidアプリケーションの Aegis-shield source code tree を参照してください。 。

16
r1k0

いくつかの調査の後、アプリケーションを使用してシングルトンを保存することは、それを再作成する準備ができていない限り、それほど素晴らしいアイデアではないことがわかりました:

アプリケーションオブジェクトにデータを保存しない

受け入れられた答え は技術的には正しいですが、すべての情報を提供するわけではありません。

上記のリンクが示唆するように、本当にそのモデルに固執したいのであれば、可能であればnullをチェックしてデータを再作成する準備ができている必要があります。

6
Rick77

@ r1k0はまさにここにあります。クラスの静的フィールドにデータを保存することは、アプリケーションプロセスの強制終了と再起動の間、それ自体では持続しません。 Androidは、メモリが必要なときにプロセス(アプリを実行中)を定期的に強制終了します。

Android doc: アクティビティ状態とメモリからの取り出し

システムがアクティビティを直接強制終了することはありません。代わりに、アクティビティが実行されているプロセスを強制終了し、アクティビティだけでなく、プロセスで実行されている他のすべてのものも破壊します。

以下のメソッドを使用して、プリミティブとSerializableおよびParcelableオブジェクトの状態を保存および復元できます。これらは、通常のアクティビティライフサイクル中に自動的に呼び出されます。

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

したがって、静的変数のみを持つクラスがある場合、onSaveInstanceState()で各フィールドの状態を保存し、onRestoreInstanceState()で復元できます。 Androidがアプリを実行しているプロセスを強制終了すると、変数の状態が保存され、Androidがアプリを復元すると、値は以前と同じ状態でメモリに復元されました。

3
eric.mcgregor