2

アクティビティの onCreate() メソッドの 1 つで、UI スレッドのハンドラをインスタンス化しています。(メモリ リークのリスクを回避するために、Handler は内部クラスではなく、通常のクラスです。)

1 つの Handler が 1 つの Thread に対応しますが、1 つの Thread には複数のハンドラーを含めることができるため (私の知る限り)、onCreate() を呼び出すたびに、新しい Handler インスタンスがインスタンス化されます。そのため、アクティビティが再度作成された場合 (onDestroy の後、その間にプロセスを強制終了することはありません)、onCreate() は別の Handler を追加しますが、古いものは削除されません。(Android ソースでは、ハンドラーはスレッドのルーパーのみを要求し、そのメッセージ キューへの参照を取得します。)

最適なソリューションは何ですか? Handler を静的変数にインスタンス化し、onCreate() で null かどうかを確認できますか。null でない場合は、新しいインスタンスを作成する必要はありませんよね?

(言うまでもなく、onDestroy() で、Handler インスタンスの Activity 参照を NULL に設定したため、Handler は Activity や関連するものをリークしていません。また、ハンドラの処理メソッドは null かどうかをチェックし、必要に応じてメッセージを破棄します。 .しかし、私の質問は、前の段落で詳述した理由により、ハンドラーがまだスレッド用に保持されているため、 onCreate 呼び出しが多いほど、UI スレッドにアタッチされた Handler インスタンスが増えるということです.私の静的ソリューションはこれに対して正しいですか?重要ではありませんが、Android は現在のスレッドに関連付けられた Handler が GC-d であることをどのように検出しますか?)

4

1 に答える 1

5

ハンドラーは、スレッド、ルーパー、またはその他によって参照されていません。ハンドラーは、ルーパーのメッセージキューにデータを入れるのに便利な方法です。

onCreate()でハンドラーをインスタンス化し、これをアクティビティーのメンバー(インスタンス)変数に割り当てると、アクティビティーがガベージコレクションされると、ハンドラーを参照するものがないため、ハンドラーもガベージコレクションされます。

したがって、onCreate()でHandlerオブジェクトを作成しても、メモリリークは発生しません。

于 2012-05-15T13:22:15.060 に答える