每日一结:内部类引起的内存泄漏

来源:互联网 发布:驾校一点通软件 编辑:程序博客网 时间:2024/06/06 05:26

内部类引起的内存泄漏

今天掘金上看了一篇文章,有一句话: 一定要多总结,对总结一下。
android常见的内存泄漏:
1. Cursor没有关闭,查询数据库后没有关闭Cursor;
2.调用registerReceiver后未调用unregisterReceiver().
3.未关闭InputStream/OutputStream
4.Bitmap使用后未调用recycle()
5.Context泄露
6.静态变量 内部类等

如下:
public class SomeActivity {
// ……
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case 0:
// do something
break;
case 1:
// do something
break;
default:
break;
}
}
};
private void someMethod () {
mHandler.sendEmptyMessage(0);
}
}
mHandler 持有SomeActivity的应用;当mHandler没有被回收,是不能被回收的,当activity 调用finsh,mhandler的消息队列没有处理完,那么activity是不会被回收的,这样也就造成了所谓的内存泄漏。

有什么解决方案?

方案#1:在关闭Activity时(finish/onStop等函数中),取消还在排队的Message:mHandler.removeCallbacksAndMessages(null);

方案#2:使用WeakReference截断StrongReference。问题的症结既然是内部类持有外部类对象的引用,那我不用内部类就行了,直接使用静态成员类。但mHandler又需要与Activity对象交互,那就来个WeakReference,指向外部Activity对象。

public class SomeActivity {
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
private WeakReference ref;
public MyHandler(SomeActivity activity) {
if (activity != null) {
ref = new WeakReference(activity);
}
}
@Override
public void handleMessage(Message msg) {
if (ref == null) {
return;
}
SomeActivity v = ref.get();
if (v == null) {
return;
}
// handle message
}
}
}
当Activity想关闭销毁时,mHandler对它的弱引用没有影响,该销毁销毁;当mHandler通过WeakReference拿不到Activity对象时,说明Activity已经销毁了,就不用处理了,相当于丢弃了消息。

尊重原创:http://www.cnblogs.com/caca/p/android_message_memory_leak.html?utm_source=tuicool&utm_medium=referral

0 0
原创粉丝点击