Handler可能造成的内存泄漏以及解决办法
- java有自己的GC机制,
- 如果GC发现一个或者一组对象为不可到达状态,则该对象从内存中回收,
- 如果一组对象中只包含互相的引用,而没有来自它们外部的引用,这任然属于不可到达,同样会被GC回收。
Android中使用Handler造成内存泄漏的原因
- Handler是Android中的内部类,一般写在Activity里面,由于内部类持有外部类的引用,在Activity被销毁的时候,如果Handler里面开了线程在做耗时操作,会因为Handler的原因造成Activity无法被回收。直到线程把事情做完。
- 如果执行了Handler的postDelayed()方法,该方法会将Handler装入一个Message,并把Message推送给MessageQueue中,那么在消息没有处理完之前,会有一条引用链,MessageQueue->Message->Handler->Acticity的链,导致Activity被持有而无法被回收。
解决方法
- 通过程序逻辑进行保护
- 在关闭Activity的时候停止线程,停止线程就切断了Handler和外部的连接线,Activity自然会在合适的时候被回收
- 如果Hanler被Messae持有引用,那么使用使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行。
将Handler声明为静态类
静态类不在持有外部类的对象,所以Activity可以被随意回收。 但是!由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。 解决办法:在Handler中增加一个队Activity的弱引用(WeakReference)
static class MyHandler extends Handler {
WeakReference<Activity > mActivityReference;
MyHandler(Activity activity) {
mActivityReference= new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
final Activity activity = mActivityReference.get();
if (activity != null) {
mImageView.setImageBitmap(mBitmap);
}
}
}
对于上面的代码,当Activity被销毁时,就算有Handler中的弱引用指向,也会被GC回收掉。
弱引用介绍
- WeakReference 弱引用,与强引用相对,它的特点是,GC在回收是会忽略掉弱引用。
- 弱引用指向的对象,只要该对象没有被强引用指向,该对象就会被GC检查到时回收掉。
关于引用方面更多的东西请移步各引用的区别