Handler警告
2092 ワード
警告メッセージ:Handler Class Should be static or Leaks Occur
この警告についてはこれまで気づかなかったが,いくつかのテストでHandlerを使用したことがある.今でも大きな問題だと気づきました汗.
まず、Handlerはメモリ漏洩のリスクがあるという意味ですが、なぜですか?
通常のサボりの書き方:
この匿名実装は一般的にActivityに直接定義されていますが、ここではJavaの観点から、私たちのHandlerはActivityの匿名内部クラスであり、内部クラスは外部クラスのインスタンスをデフォルトで持っています.外部クラスは現在のActivityであり、一般的にLooperにメッセージを送信するメッセージにはHandlerリファレンス(handlerMessageメソッドを呼び出す必要がある)が含まれていますが、LooperのライフサイクルはApplicationと一致しています.その結果、より長いライフサイクルを持つLooperはActivityインスタンスを持ち、メッセージにActivityリファレンスが遅延すると解放できない(この場合、このActivityはgcによって回収できない)ため、メモリが漏洩する(参照:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html).
この問題を解決する方法:サボらないで、Handlerを別のclassファイルに書きます. は、Handerを静的内部クラスとして定義する(静的内部クラスは外部クラス参照を持たない).
ここでは、Activityインスタンスを保持するために弱いインデックスを使用します.弱参照:http://blog.csdn.net/jinhuiyu/article/details/3709767
この方法は同様にThreadリークの問題を解決することができ、以下を参照してください.http://blog.csdn.net/zhuanglonghai/article/details/37909553
3.最後に、onDestroyで未処理のメッセージをすべてキャンセルするのも最も簡単です.
Activity destroyの後で処理しなければならない処理がある場合は、Handlerの代わりにサービスなどの他の方法を使用することも考えられます.
メモリリークリファレンス:http://www.cnblogs.com/qianxudetianxia/p/3645106.html
この警告についてはこれまで気づかなかったが,いくつかのテストでHandlerを使用したことがある.今でも大きな問題だと気づきました汗.
まず、Handlerはメモリ漏洩のリスクがあるという意味ですが、なぜですか?
通常のサボりの書き方:
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
TextView textView = (TextView) findViewById(R.id.final_txt);
textView.setText(msg.getData().getString("msg"));
}
};
この匿名実装は一般的にActivityに直接定義されていますが、ここではJavaの観点から、私たちのHandlerはActivityの匿名内部クラスであり、内部クラスは外部クラスのインスタンスをデフォルトで持っています.外部クラスは現在のActivityであり、一般的にLooperにメッセージを送信するメッセージにはHandlerリファレンス(handlerMessageメソッドを呼び出す必要がある)が含まれていますが、LooperのライフサイクルはApplicationと一致しています.その結果、より長いライフサイクルを持つLooperはActivityインスタンスを持ち、メッセージにActivityリファレンスが遅延すると解放できない(この場合、このActivityはgcによって回収できない)ため、メモリが漏洩する(参照:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html).
この問題を解決する方法:
private static class MyHandler extends Handler {
private final WeakReference<ThiredActivity> mActivity;
private MyHandler(ThiredActivity mActivity) {
this.mActivity = new WeakReference<ThiredActivity>(mActivity);
}
@Override
public void handleMessage(Message msg) {
ThiredActivity activity = mActivity.get();
if (activity != null) {
TextView textView = (TextView) activity.findViewById(R.id.final_txt);
textView.setText(msg.getData().getString("msg"));
}
}
}
ここでは、Activityインスタンスを保持するために弱いインデックスを使用します.弱参照:http://blog.csdn.net/jinhuiyu/article/details/3709767
この方法は同様にThreadリークの問題を解決することができ、以下を参照してください.http://blog.csdn.net/zhuanglonghai/article/details/37909553
3.最後に、onDestroyで未処理のメッセージをすべてキャンセルするのも最も簡単です.
mHandler.removeCallbacksAndMessages(null);
Activity destroyの後で処理しなければならない処理がある場合は、Handlerの代わりにサービスなどの他の方法を使用することも考えられます.
メモリリークリファレンス:http://www.cnblogs.com/qianxudetianxia/p/3645106.html