In Android asynchronous message processing,
new Handler() { @Override publicvoidhandleMessage(Message msg) { // } };
But when we write this, the compiler gives a warning prompt: The handler class should be static and memory leaks can occur.
Reason:
in Java, non-static inner classes and anonymous inner classes implicitly hold references to their external classes. Static inner classes do not hold references to external classes.
Here handler is an instance of an anonymous inner class that holds a reference to the activity outside, so when handler accompanies a time-consuming background thread, activity cannot be reclaimed and memory leaks.
Workaround:
One: Declare handler as a static inner class.
Because static inner classes do not hold references to external classes, they do not cause memory leaks for external class instances. Because handler no longer holds references to external class objects, the program does not allow you to manipulate objects in the activity in handler. So if you want to invoke an external activity in a static inner class, we use a weak reference to handle it (WeakReference).
Private Static class myhandler extends Handler { Private FinalWeakreference<sampleactivity> mactivity; Public MyHandler(sampleactivity activity) {mactivity =NewWeakreference<sampleactivity> (activity); }@Override Public void Handlemessage(Message msg) {Sampleactivity activity = mactivity.get ();if(Activity! =NULL) {// ...} } }
II: postdelayed (New Runnable (), 10000) situation
mHandler.postDelayed(new Runnable() { @Override publicvoidrun() { // } 10000);
In Handler's Post method we added an anonymous runnable, and I deferred it for 10 seconds.
Deferred messages are persisted in the main thread message queue until they are processed. New Runnable is also an anonymous inner class implementation, and also holds references to activity.
At this point we also need to set the runnable as a static member property.
privatestaticfinalnew Runnable() { @Override publicvoidrun/* ... */ } };
At the same time OnCreate () in mhandler.postdelayed (srunnable, 10000);
Another method is to use the handler Removecallbacksandmessages () method to remove the message object from the message queue.
When the argument is null, you can erase all the runnable and message associated with the handler, and we call the OnDestroy method to clean up all the messages.
protectedvoidonDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages(null); };
Summary:
When we use a non-static inner class, it is possible to cause a memory leak if its instance holds an object whose lifetime is greater than its outer class object. Scheme:
- Use static internal classes;
- Use weak references for all variables in the handler/runnable.
About references:
? 强引用:如“Object obj = new Object()”,这类引用是Java程序中最普遍的。只要强引用还存在,垃圾收集器就永远不会回收掉被引用的对象。 ? 软引用:它用来描述一些可能还有用,但并非必须的对象。在系统内存不够用时,这类引用关联的对象将被垃圾收集器回收。JDK1.2之后提供了SoftReference类来实现软引用。 ? 弱引用:它也是用来描述非需对象的,但它的强度比软引用更弱些,被弱引用关联的对象只能生存岛下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK1.2之后,提供了WeakReference类来实现弱引用。 ? 虚引用:最弱的一种引用关系,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的是希望能在这个对象被收集器回收时收到一个系统通知。JDK1.2之后提供了PhantomReference类来实现虚引用。
Reference
Http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1123/2047.html
http://blog.csdn.net/ns_code/article/details/18076173
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Memory leaks due to Android development--handler