Android 静的オブジェクトのライフサイクル
-
20-09-2019 - |
質問
イベント検索アプリケーションを作成しています。ある画面から検索条件を設定し、別の画面に入力すると、ユーザーは 3 番目の画面から検索条件を編集して、4 番目の画面に移動できます。
上記のタスクを達成するために、私はアプリケーションの周りの値を記憶する静的オブジェクトを使用しているので、余分なことをする必要はありません。
しかし、Androidの静的オブジェクトのライフサイクルについて、メモリ不足が見つかった場合、Androidは静的オブジェクトを削除してしまうのではないかと心配しています。
Androidはマルチタスクをサポートしているため、ユーザーが別のアプリケーションに切り替え、ユーザーが戻ってきたときにアプリケーションがおかしくなり始めた場合、マルチタスク時に静的オブジェクトは削除されますか?何か案が ??また、シングルトンメソッドを介して静的オブジェクトを保持する方が良いアプローチであることを提案しますか?
解決
少し背景から始めましょう:アプリケーションを起動すると何が起こるでしょうか?
OS はプロセスを開始し、それに一意のプロセス ID を割り当て、プロセス テーブルを割り当てます。プロセスは DVM (Dalvik VM) のインスタンスを開始します。各アプリケーションは DVM 内で実行されます。
DVM は、クラスのロード/アンロード、インスタンスのライフサイクル、GC などを管理します。
静的変数の存続期間:静的変数は、クラスが JVM によってロードされるときに存在し、クラスがアンロードされるときに消滅します。
したがって、Android アプリケーションを作成して静的変数を初期化すると、次のいずれかが起こるまで、その変数は JVM 内に残ります。
1.クラスがアンロードされる
2.JVM がシャットダウンする
3.プロセスが死ぬ
別のアプリケーションの別のアクティビティに切り替えても、上記 3 つのいずれも発生しない場合でも、静的変数の値は保持されることに注意してください。上記 3 つのいずれかが発生すると、静的値はその値を失います。
数行のコードでこれをテストできます。
- アクティビティの onCreate で初期化されていない静的値を出力します -> null を出力する必要があります
- 静的を初期化します。それを印刷します -> 値は null ではありません
- 戻るボタンを押してホーム画面に移動します。注記:ホーム画面も別のアクティビティです。
- アクティビティを再度起動します -> 静的変数は null ではなくなります
- DDMS からアプリケーション プロセスを強制終了します (デバイス ウィンドウの [停止] ボタン)。
- アクティビティを再起動します -> 静的値は null 値になります。
それが役立つことを願っています。
他のヒント
シングルトン パターンも静的変数の使用に基づいているため、実際には同じ状況になります。静的なアプローチはほとんどの場合機能しますが、場合によっては、メモリがいっぱいで、アプリケーションが次の画面に移動する前に別のアクティビティがフォアグラウンドになると、アクティビティのプロセスが強制終了され、静的な値が失われる可能性があります。ただし、Android では、状態間で値を保持したり、それらを送信したりするためのいくつかのオプションが提供されています。
- 意図を使用して、アクティビティからアクティビティまで検索基準を渡すことができます(Web HTTPリクエストと同様)
- アプリケーションの設定を使用すると、値を保存し、それらを必要とするアクティビティでそれらを取得できます
- sqliteデータベースを使用して、それらをテーブルに保持し、後で取得することができます
- 再起動時にフィールドが以前に選択された値で満たされるようにアクティビティ状態を保存する必要がある場合、onsaveinstanceState()アクティビティ方法を実装できます - これは、状態のアクティビティの持続性の間に推奨されないことに注意してください。
プリファレンス、インテント、sqlite データベースの使用方法のコード例をいくつか確認できます。 aegis-shield ソース コード ツリー Google コードまたは他のオープンソース Android アプリケーション内で。
いくつかの研究の後、それはあなたがそれを再作成する準備ができている場合を除き、シングルトンを格納するためのアプリケーションを使用すると、アイデアのその偉大ではないことが判明します:
/ <アプリケーション・オブジェクトにデータを格納しないでくださいA>
には、技術的に正しいですhref="https://stackoverflow.com/a/1944564/2177061">ながら、それはすべての情報を提供しないようにします。
あなたが本当にそのモデルに固執したい場合は、上記のリンクは、示唆するように、あなたは、可能な場合は、nullをチェックして、データを再作成する準備する必要があります。
@ r1k0はここです。アプリケーション・プロセスが強制終了して再起動しても、クラスの静的フィールドで保存するデータは、独自に保持されません。 Androidは日常、それはメモリを必要とするとき(アプリケーションを実行している)のプロセスを強制終了します。
アンドロイドDOCパー:メモリから活動状態と排出に、
システムが直接活動を殺すことはありません。代わりに、それは殺します 活動は活動だけでなく破壊し、実行されるプロセス しかし、他のすべては、同様に、プロセスで実行されている。
あなたは、以下の方法を使用して、同様シリアライズとParcelableオブジェクトをプリミティブの状態を保存し、復元することができます。これらは自動的に通常の活動のライフサイクルと呼ばれています。
protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}
だから、あなただけの静的変数を持つクラスを持っている場合、あなたは)(onSaveInstanceState()内の各フィールドの状態を保存し、onRestoreInstanceStateでそれらを復元することができます。 Androidのアプリが実行されているプロセスを強制終了すると、あなたの変数の状態が保存され、Androidのアプリを復元するとき、値が以前と同じ状態でメモリに復元されます。