Handlerメッセージ構造の注意点
2919 ワード
参照リンク:Handlerのいくつかの使用姿勢を説明します.
handlerメカニズムは、スレッドのメッセージ伝達を簡単に処理することができますが、同時にhandlerを使用するには、注意すべき点があります.
この章を通して知ることができます.は、ハードラー をサブスレッドに使用する. Handlerを使用してメモリの漏洩を避ける サブスレッドでは、Handlerを使用します.
一般的にはHandlerを使用する場合、メインスレッドで使用します.しかし、Handlerはサブスレッドでも使用できます.
Handlerを使用する場合はメモリの漏洩を避ける
私たちは普段ハンドルを使う時は、直接的に実用化して、他のところで使うことが多いです.
この問題を解決するには、外部Activityで静的な内部クラスを定義することができます.次に、外部クラスを持つ参照を弱引用に変更します.ごみを回収する時、弱い引用の対象を自動的に回収するからです.
handlerメカニズムは、スレッドのメッセージ伝達を簡単に処理することができますが、同時にhandlerを使用するには、注意すべき点があります.
この章を通して知ることができます.
一般的にはHandlerを使用する場合、メインスレッドで使用します.しかし、Handlerはサブスレッドでも使用できます.
new Thread(()->{
Handler threadHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
}).start();
ただし、直接にサブスレッドに初期化すると、Handlerに異常が発生します. java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.(Handler.java:204)
at android.os.Handler.(Handler.java:132)
Handler初期化はLooperが必要ですので、Looperを初期化する必要があります.new Thread(()->{
Looper.prepare();
Handler threadHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
Log.i("threadHandler",(CharSequence) msg.obj + "23333");
}
}
};
// Looper.loop();
}).start();
これでエラーはないですが、これではメッセージを処理できません.Looper.loop()メソッドを呼び出してループ処理メッセージを開始する必要があります.Handlerを使用する場合はメモリの漏洩を避ける
私たちは普段ハンドルを使う時は、直接的に実用化して、他のところで使うことが多いです.
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//
}
};
しかし、それはメモリ漏れです.handlerは非静的な匿名の内部クラスであるため、外部クラスの引用をデフォルトで保持しています.外部activityが突然閉鎖された場合、Message Queのメッセージはまだ処理されていません.メモリ漏れの原因となります.MessageはHandlerオブジェクトを持っているため、Handlerは外部activityの引用を持っているため、外部activityは回収できなくなります.この問題を解決するには、外部Activityで静的な内部クラスを定義することができます.次に、外部クラスを持つ参照を弱引用に変更します.ごみを回収する時、弱い引用の対象を自動的に回収するからです.
public class TextActivity extends AppCompatActivity {
private MyHandler handler = new MyHandler(this);
private static class MyHandler extends Handler {
WeakReference mWeakActivity;
public MyHandler(HandlerActivity activity) {
this.mWeakActivity = new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
final TextActivity mActivity = mWeakActivity.get();
if (mActivity != null) {
//
}
}
}
}
もう一つの簡単な方法があります.外部のActivityが廃棄された時にメッセージのキューを削除することです.handlerを釈放したのと同じです.ゴミの回収はスムーズに行われます. @Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
}