匿名内部のHandlerクラスのメモリ漏洩を解決する方法
1833 ワード
説明
handlerを使用する場合、スレッド間操作の問題を解決するために一般的に使用されます.一般的にスレッドを開くと、処理に時間がかかるため、メモリの漏洩を招く可能性があります.ここでは、このようなメモリ漏洩を処理する方法について説明します(同時に、このような匿名の内部クラスによるメモリ漏洩の問題、例えばThreadなどを解決することができます).
Handlerがメモリ漏洩の原因(面接時に聞かれた):Handlerの匿名内部クラスの形式で問題を処理する場合、Handlerオブジェクトは私たちのページactivityまたはfragmentのオブジェクトを保持し、Handlerはメッセージを送信する際にメッセージオブジェクトをメッセージキューに存在させ、すぐに処理するとは限らない.この場合、ページが閉じると、保持している現在のページのオブジェクトが参照され、破棄できず、漏洩します.(メッセージが配信された後に対応するコールバック操作を行うと、現在のページが終了しているため、一部のリソースが回収される可能性があります.)
匿名の内部クラスの代わりに静的内部クラスを使用する
静的内部クラスを使用する理由は、外部クラスの参照を持たないためです.また、処理に時間がかかるHandlerオブジェクトのライフサイクルが、現在のページのライフサイクルと同期することも保証されます.(この方法はThreadなどにも適用される)
使用方法の概要
Handlerは静的であるため、内部のすべてのオブジェクトは静的である必要があり、処理後の結果をUIスレッド処理に置く必要があります.データを転送するためにコールバックインタフェースを宣言する必要があります.
MyHandlerにコンストラクションメソッドとhandlerMessage()メソッドを追加します.ここでは結果を返すだけで、他の操作も可能です.場合によっては.
次に、MyHandlerオブジェクトをインスタンス化し、メッセージを送信する必要があります.
ここでは、UIスレッドの転送に成功したデータを見て、対応する処理をすればいいです.コードの似たような処理を見るのは簡単ですが、ここでメモを取ってみましょう.
handlerを使用する場合、スレッド間操作の問題を解決するために一般的に使用されます.一般的にスレッドを開くと、処理に時間がかかるため、メモリの漏洩を招く可能性があります.ここでは、このようなメモリ漏洩を処理する方法について説明します(同時に、このような匿名の内部クラスによるメモリ漏洩の問題、例えばThreadなどを解決することができます).
Handlerがメモリ漏洩の原因(面接時に聞かれた):Handlerの匿名内部クラスの形式で問題を処理する場合、Handlerオブジェクトは私たちのページactivityまたはfragmentのオブジェクトを保持し、Handlerはメッセージを送信する際にメッセージオブジェクトをメッセージキューに存在させ、すぐに処理するとは限らない.この場合、ページが閉じると、保持している現在のページのオブジェクトが参照され、破棄できず、漏洩します.(メッセージが配信された後に対応するコールバック操作を行うと、現在のページが終了しているため、一部のリソースが回収される可能性があります.)
匿名の内部クラスの代わりに静的内部クラスを使用する
private static class MyHandler extends Handler();
静的内部クラスを使用する理由は、外部クラスの参照を持たないためです.また、処理に時間がかかるHandlerオブジェクトのライフサイクルが、現在のページのライフサイクルと同期することも保証されます.(この方法はThreadなどにも適用される)
使用方法の概要
Handlerは静的であるため、内部のすべてのオブジェクトは静的である必要があり、処理後の結果をUIスレッド処理に置く必要があります.データを転送するためにコールバックインタフェースを宣言する必要があります.
interface Listener{
void onSuccess(Message msg);
}
MyHandlerにコンストラクションメソッドとhandlerMessage()メソッドを追加します.ここでは結果を返すだけで、他の操作も可能です.場合によっては.
private static class MyHandler extends Handler {
Listenerlistener;
MyHandler (Listener listener) {
this.listener = listener;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//TODO do something
listener.onSuccess(msg);
}
}
次に、MyHandlerオブジェクトをインスタンス化し、メッセージを送信する必要があります.
private MyHandler myHandler = new MyHandler (new Listener() {
@Override
public void onSuccess(Message msg) {
String url = (String) msg.obj;
//
}
});
//
new Thread(new Runnable() {
@Override
public void run() {
myHandler.sendMessage(msg);
}
}).start();
ここでは、UIスレッドの転送に成功したデータを見て、対応する処理をすればいいです.コードの似たような処理を見るのは簡単ですが、ここでメモを取ってみましょう.