提示说:不要把「Do not place android context classes in static fields, this is a memory leak.」
我知道activity context 不应该被放到static fields里面因为它在app生命周期内一直存在,而且如果它通过构造函数传递给其他class的话,其他class也会一直不被回收。
但为什么ImageView
不能是static(我发现SwipeRefreshLayout也不行)?是因为ImageView包含context
?Button
和TextView
之类的view就没有这种问题。
アクティビティでレイアウトを埋めるには、次の手順を実行できます:
リーリーどちらの方法であっても、塗りつぶされたビューは、アクティビティへの参照であるコンテキストへの参照を保持していることがわかります。
この時点で塗りつぶされたビューが静的に変更されると、静的オブジェクトは次のようになります。持続し続ける アクティビティへの参照があるため、アクティビティを破棄できず、アクティビティ内のすべてのコントロールが完全に破棄およびリサイクルされず、最終的にメモリ リークが発生します。
追記: 静的ビューを使用する理由はありますか? 特別なビジネス要件はありますか?
静的変数はメモリ ブロック内に個別に存在します。コントロール (質問の ImageView) はアクティビティへの参照を保持します。この場合、メモリ内に常に参照 (ポインタ理解) が存在するため、アクティビティを完全に破棄することはできません。そのため、アクティビティをリサイクルすることはできず、当然メモリ リークが発生します。
Android では静的に変更されたコントロールを使用しないことをお勧めします。
ビューはコンテキストを保持する必要があります (そうしないと、
setXXX(int resid)
クラスの関数を実装できません)Button/TextView が警告を出さない理由がわかりません
静的変数は自動的にリサイクルできません
。ビューを静的変数として設定すると、ビューはアクティビティへの参照を保持します。今度はアクティビティもリークされます
静的なライフサイクルは現在のアクティビティよりも非常に長いため
これが Java の基礎です。クラス ファイルがバイトコードにコンパイルされた後、静的変数はメソッド領域がロードされるときに初期化され、静的変数は変更されずに常に存在します。 activity. は、new 時にヒープ内のスペースを適用します。アクティビティが役に立たない場合、アクティビティの
context
が保持されているため、gc は gc-root に従ってトラバースします。 🎜> そのため、仮想マシンがプロセスを終了する (つまり、アプリが停止する) まで、GC をリサイクルできず、メモリ リークが発生します。ImageView view = LayoutInflater.from(context).inflate(R.layout.test,null);