AndroidでHandlerがメモリの漏洩を引き起こす可能性があります
1339 ワード
まずコードを見てみましょう.
このような書き方はeclipseがleakのヒントを与えるThis Handler class should be static or leaks might occur...、メモリリークが発生する可能性があることを示します.1)Handlerオブジェクトがプライマリスレッドに作成されると、Looperのmessage queueに関連付けられます.メッセージキューにMessageが追加するとMessageは現在のHandler参照を保持し、Looperが現在のメッセージに処理するとHandler#handleMessage(Message)が呼び出される.2)javaでは、no-staticの内部クラスが現在のクラスの参照を暗黙的に保持します.staticのクラスはありません.3)まとめ:非静的内部クラスHandlerは外部クラスオブジェクトの参照を持つため,HandlerはMessage処理によりメモリに常駐する可能性がある.これにより、外部のActivityやServiceが破棄された後、GCに回収されず、メモリが漏れることもあります.
このため,外部クラスの漏洩を避けるためには,Handlerをstaticネストクラスとして宣言し,外部クラスへの弱い適用を用いるべきである.
1. private Handler mHandler = new Handler() {
2. @Override
3. public void handleMessage(Message msg) {
4. // ...
5. }
6. };
このような書き方はeclipseがleakのヒントを与えるThis Handler class should be static or leaks might occur...、メモリリークが発生する可能性があることを示します.1)Handlerオブジェクトがプライマリスレッドに作成されると、Looperのmessage queueに関連付けられます.メッセージキューにMessageが追加するとMessageは現在のHandler参照を保持し、Looperが現在のメッセージに処理するとHandler#handleMessage(Message)が呼び出される.2)javaでは、no-staticの内部クラスが現在のクラスの参照を暗黙的に保持します.staticのクラスはありません.3)まとめ:非静的内部クラスHandlerは外部クラスオブジェクトの参照を持つため,HandlerはMessage処理によりメモリに常駐する可能性がある.これにより、外部のActivityやServiceが破棄された後、GCに回収されず、メモリが漏れることもあります.
このため,外部クラスの漏洩を避けるためには,Handlerをstaticネストクラスとして宣言し,外部クラスへの弱い適用を用いるべきである.
1. static class MsgHandler extends Handler {
2. private WeakReference<Activity> mActivity;
3.
4. MsgHandler(Activity activity) {
5. mActivity = new WeakReference<Activity>(activity);
6. }
7.
8. @Override
9. public void handleMessage(Message msg) {
10. Activity activity = mActivity.get();
11. if (activity != null) {
12. activity.handleMessage(msg);
13. }
14. }
15. }
16.
17. private Handler mHandler = new MsgHandler(this);