This way of creating handler causes a memory leak, because Mhandler is an instance of the handler non-static anonymous inner class, so it holds a reference to the external class activity, and we know that Message Queuing is constantly polling for processing messages in a looper thread. So when this activity exits, there is an unhandled message in the message queue, or a message is being processed, and the message in messages queue holds a reference to the Mhandler instance, and Mhandler holds a reference to the activity. Therefore, the memory resources of the activity cannot be reclaimed in a timely manner, causing a memory leak, so another approach is:
public class Mainactivity extends Appcompatactivity {
Private MyHandler Mhandler = new MyHandler (this);
Private TextView Mtextview;
private static class MyHandler extends Handler {
Private weakreference<context> reference;
Public MyHandler (Context context) {
Reference = new Weakreference<> (context);
}
@Override
public void Handlemessage (Message msg) {
Mainactivity activity = (mainactivity) reference.get ();
if (activity! = NULL) {
Activity.mTextView.setText ("");
}
}
}
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Mtextview = (TextView) Findviewbyid (R.id.textview);
LoadData ();
}
private void LoadData () {
... request
Message message = Message.obtain ();
Mhandler.sendmessage (message);
}
}
Create a static handler inner class, and then use weak references to objects held by handler so that the objects held by the handler can be reclaimed at the time of collection, so that the activity leaks are avoided, but messages in the Looper thread's message queue may still be pending. So we should remove the message in the message queue at the time of the activity's destroy or stop, more precisely as follows:
public class Mainactivity extends Appcompatactivity {
Private MyHandler Mhandler = new MyHandler (this);
Private TextView Mtextview;
private static class MyHandler extends Handler {
Private weakreference<context> reference;
Public MyHandler (Context context) {
Reference = new Weakreference<> (context);
}
@Override
public void Handlemessage (Message msg) {
Mainactivity activity = (mainactivity) reference.get ();
if (activity! = NULL) {
Activity.mTextView.setText ("");
}
}
}
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
Mtextview = (TextView) Findviewbyid (R.id.textview);
LoadData ();
}
private void LoadData () {
... request
Message message = Message.obtain ();
Mhandler.sendmessage (message);
}
@Override
protected void OnDestroy () {
Super.ondestroy ();
Mhandler.removecallbacksandmessages (NULL);
}
}
Use Mhandler.removecallbacksandmessages (null) to remove all messages and all runnable in the message queue. Of course, you can also use Mhandler.removecallbacks () or mhandler.removemessages () to remove the specified runnable and message.
Lao Li share: Android performance optimized memory leak 2