web-dev-qa-db-ja.com

Androidの静的変数の寿命

メインアクティビティで変数を静的として宣言および初期化すると、アクティビティが破棄されます。変数のコンテンツに引き続きアクセスできますか?

たとえば、この変数に保存するAsyncTaskに常にアクセスするには?私が望むのは、方向が変わった後でもアクセスできるようにすることです。

33
maysi

静的変数はクラスに関連付けられており、クラスがメモリ内にある限り存続し、クラスがアンロードされると破棄されます(めったに起こりません)。

Androidアプリケーションを閉じると、完全に閉じられないことがわかりました。最近のアプリケーションスタックに残っています。

他のアプリにメモリが必要な場合、Android自体が最近のアプリを削除しました

18
Tarun Varshney

プロセスが強制終了されると、すべての静的変数が再初期化されますがデフォルト値になります。

これは主に、アプリケーションを再起動すると新しいインスタンスが作成され、静的変数が再初期化されるためです。

5
JNL

変数のコンテンツに引き続きアクセスできますか?

「破壊された」とは、ユーザーが「戻る」を押したようなことを意味すると仮定します。はい。

静的データメンバは、プロセスが終了するまで存続します。

たとえば、この変数に保存するAsyncTaskに常にアクセスするには?私が望むのは、方向が変わった後でもアクセスできるようにすることです。

それは適切な解決策ではありません。保持されたフラグメントを使用するか、または se onRetainNonConfigurationInstance() を使用します。

4
CommonsWare

静的変数はクラス自体に関連付けられています。クラスがメモリ内にある限り、変数は保持されます。

クラスは、Permanent Generationのメモリスペース(世代別GCの動作の詳細については、こちらを参照してください https://www.Oracle.com/webfolder/technetwork/tutorials/obe/Java/gc01/index.html )。

https://developer.Android.com/topic/performance/memory-overview を見ると、Androidでメモリがどのように管理されているかをよりよく理解できますが、アプリが非常に何かをしている場合を除きます珍しいことに、永続世代には、すべてのクラスを保持するために必要なすべてのメモリが割り当てられ、ガベージコレクションは行われません。

向きを変更しても静的変数はクリアされませんが、静的変数を使用することが目的ではない場合はあまり適切ではありません。 setRetainInstanceなどを使用して、向きが変わってもインスタンスの状態を保持できます( Android:向きの変更時にクラス変数がクリアされないようにする方法 を参照)

1
Alon Bar David

外側のクラスがメモリにロードされると、静的変数が作成されます。静的変数は、ロード時に静的ブロックで初期化するか、コードが既に実行されている間に初期化できます。静的変数は、型の単一インスタンスではなく型に関連付けられます。これは、いったん静的変数が作成されると、それを含むプロセス(in Androidアプリケーションとともに存在します。)それが引き起こす可能性のある問題は次のとおりです。

  • コンテキストリーク(アクティビティのような):静的変数は、コンテキストへの参照を保持するか、オブジェクトへの参照を保持します(ビューなど)。
  • メモリへの大きな負担:アプリケーションよりもライフスコープが短い型で静的変数を使用する場合、プロセスはすべての静的変数を有効に保ちます。たとえば、10個のアクティビティでは、ビットマップを静的変数として保持します。この場合、すべてのビットマップはライブであり、メモリ内の場所を占有します。最後に、メモリとシステムは負担に耐えられず、MemoryOutBoundExceptionをスローできません。
  • クラッシュ:たとえば、シナリオで、アクティビティにオブジェクトを作成してから、そのオブジェクトを静的変数としてアクティビティに保存します。その後、次のアクティビティに進みます。 2番目のアクティビティでは、前のアクティビティの静的変数がnullではなく、ほとんどの場合trueであることを確認します。ただし、システムがプロセスを強制終了して再作成した場合、静的変数はそのオブジェクトを永続化しません。私が言いたいのは、イベント駆動型の環境では、静的変数を管理することは簡単なことではないということです。

あなたの場合:ViewModelアーキテクチャコンポーネントは、構成の変更後もオブジェクトを保持します。使用できますが、コンテキストリークに注意する必要があります。別のオプションは、UIなしでフラグメントを使用することです。フラグメント内で関数setRetainInstance(true)を呼び出すと、システムは構成の変更後もこのフラグメントを保持します。このフラグメントはデータを保持し、構成の変更が発生した後、フラグメントマネージャーを介してこのフラグメントを取得できます。実際、後者のオプションはViewModelの基本的なメカニズムです。 AsyncTaskのようなマルチスレッドの場合、別のスレッドで実行されている操作はコンテキストへの参照を保持しません。別のレイヤーでタスクを実行してから、viewModelまたは保持されたフラグメントの必要なフィールドを更新する必要があります。

1
M.ekici

静的変数の値は、クラスがロードされている限り持続します-アクティビティのライフサイクル(onCreate、...、onDestroy)とはほとんど関係ありません

コードからクラスに初めてアクセスすると、クラスがロードされ、その後、アンロードする理由があるまで消えません。

Androidは、タスクキラーを介して、またはアプリがアクティブでなくなってメモリが少なくなったときに、アプリがメモリから完全に削除されると、クラスをアンロードします。

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

0
Ashok Kumar

私はついにあなたに参照を見つけたと信じています-

ガベージコレクターは、未使用のオブジェクトを自動的にクリーンアップします。プログラムがそれ以上の参照を保持しない場合、オブジェクトは使用されません。参照を保持する変数をnullに設定することにより、明示的に参照を削除できます。

https://docs.Oracle.com/javase/tutorial/Java/javaOO/summaryclasses.html

明確にするために、静的変数が初期化されたままになり、クラスが適切にガベージコレクションされる(メモリリークとも呼ばれる)ことを防ぐことができます。

0
Brandon McAnsh

最近のアプリからそれらをクリアしない限り、戻るボタンを押してアプリを閉じても、それらは維持されます。

0
steve moretz

静的変数は、クラスのライフサイクルに関連付けられています。アクティビティが破棄されると、その静的変数もクリーンアップされます。

それでもその変数にアクセスしたい場合、2つのオプションがあります-

  1. onSaveInstanceStateをオーバーライドし、必要な変数を保存してonRestoreInstanceStateに復元します
  2. Applicationクラスに変数を保存し、いつでもどこでもアクセスできます。
0
Shivam

はい、設定した値は、アクティビティが閉じた後も保持されますが、アプリケーションが閉じた後は保持されません。

0
Hasnain Sabir

Androidには 空のプロセス という概念があります。これは、すべてのコンポーネント(アクティビティ、サービス、および/またはブロードキャストレシーバー)が破壊されても、ユーザーが頻繁に使用する場合、メモリからアプリを削除できないことを示しますこの場合、静的変数は完全には消去されません。

アプリケーションクラスは、アプリケーションの起動時に適切に作成され、ユーザーがアプリを終了すると消去されるため、コンポーネント間で一時変数を共有する最良の方法です。

参考: http://skillgun.com/question/9849/Android-provab/face-to-face-round/if-i-close-the-application-will-it-destroy-all-the-静的変数

0

私は実際に誰も参照を見つけることができなかったことに驚いています。ウィキペディアにあります:

...静的 変数allocated "statically"になっている変数です。つまり、その有効期間(または "エクステント")はプログラムの実行全体です。これは、短命の 自動変数 とは対照的です。そのストレージは スタック割り当て であり、 呼び出しスタック で割り当て解除されます。 オブジェクト とは対照的に、そのストレージは 動的に割り当てられます であり、 ヒープメモリ で割り当て解除されます。

この定義は、一般的なプログラミング言語用です。ただし、Androidへの参照として使用できます。ただし、オブジェクト指向プログラミング言語では:

オブジェクト指向プログラミング には、 静的メンバー変数 という概念もあります。これは、静的に定義されたクラスの "クラス変数" ですつまり、すべての インスタンス (オブジェクト)で共有され、これらのオブジェクトのメンバー変数としてアクセス可能な、特定のクラスの メンバー変数 です。動的に定義されたクラスのクラス変数は、実行時にクラスを定義できる言語では、クラスが定義されるときに割り当てられ、静的ではありません。

つまり、Javaが使用されているAndroid静的変数のライフタイムは、アプリまたはそれを使用しているインスタンスのライフタイムと同じです。その静的変数は実行時に作成されません。

0
Gaurav Mall