匿名内部のHandlerクラスのメモリ漏洩を解決する方法

1833 ワード

説明
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スレッドの転送に成功したデータを見て、対応する処理をすればいいです.コードの似たような処理を見るのは簡単ですが、ここでメモを取ってみましょう.