スレッド間通信を担当する最も一般的に使用されるタイプ、などのAndroidハンドラ。
関連するクラスは、ルーパー、メッセージキュー、メッセージを持っている。これは主にハンドラのメモリリークにつながるだけでなく、いくつかの一般的な問題についての記録です。
A.ハンドラは、メモリリークにつながります
例えば、アクティビティが終了しましたが、OOMにつながる可能性が厳しい場合には、GCを回収することができない、メモリリーク現象は、もはや必要なオブジェクトは、GCを回収することができません。
メモリリークの理由ハンドラリードは非静的匿名の道の新しいクラスによって作成された活動Handlerオブジェクト内、そしてHandlerオブジェクトは、暗黙のうちに外活動のホールドクラスに参照(JAVA中央アフリカの静的内部クラスを保持している場合参照)、次にアクティビティハンドラ破壊場合、ニュース処理されていない、ハンドラオブジェクトはアクティビティがメモリリークを解放することができない、その結果、アクティビティへの参照を保持つながります。
友人は、オーバーヘッドの活動を終了した後に発生しますが、上記のメモリリークの問題を解決しなかったhandlerMessageを続けるメッセージを削除するハンドラのremoveCallbacksAndMessagesを呼び出して終了し、このアプローチは確かにHandlerオブジェクトを減らすことができ、時間の活動で語りました。その理由は、ハンドラが、メッセージキューにメッセージオブジェクトを送信Mesaageオブジェクト対象がハンドラオブジェクトアクティビティをリサイクルすることができない、その結果、その後ハンドラオブジェクトは再利用することができない、Meassageハンドラが存在するオブジェクトを参照する場合、メッセージ・リファレンスを送信保持し、ありますメモリリーク。
解決策は、
1.静的内部クラスは、外側のクラスへの参照を保持していないので、ハンドラは、静的と定義されます
図2は、実施ハンドラアクティビティオブジェクトのコンストラクタを通過し、外部ハンドラアクティビティクラスのメンバ変数の動作のために、静的内部クラスとして定義され、その後確実にするために、弱参照アクティビティ着信オブジェクトで包み、そのGCの各アクティビティオブジェクトを再利用することができます。
活性は、上記の2つの段階でメモリリークハンドラを使用する場合、問題が存在しないことを保証することができます。上述した実施形態は、パッケージが静的ハンドラを避けるために各時間を定義するために、実際の使用を使用することによって簡略化する、原則です。
二つ。ルーパー無限ループに関連する問題
ルーパーは、ルーパーがメインスレッドにつながるメインスレッドがANRを引き起こし、ブロックされた、無線ループのですか?
これはインタビューの質問の比較的高いレベルではありません、答えは何も明らかにされていますが、答えるために必要なものを整理したいと思います。
答えを合理化することである:メインスレッド開始直後に終了しないことを確実にするルーパー無限ループにより、メインスレッドアンドリュース、そうでない場合、プロセスはメインスレッドを終了します引き出さ;そして私達はANRの操作に問題があるときので活動、サービス、BroadcastReceiverでですコールバックはANRにタイムアウトの鉛を取るコードを実行し、時間のかかる操作すべきではありません。
原理は、システムサーバプロセスが存在することになるたシステムであり、アプリケーション層におけるAPPプロセスは、プロセス・アクティビティのonCreate、onResume、onPauseのシステムサーバメインスレッドを実行している他のシステムは、APPバインダー通信、及び最終的にメッセージによってコールバック・プロセスに渡されメインスレッドに送信すると、対応するコールバックを実行しますが、コールバックメッセージAPPプロセスを受け取った場合は、ANRの問題は、このようなのonCreateで一定時間を超えて時間のかかる操作を実行すると、このプロセスでは、とANRの後に存在していません。