一、怎么发生的内存泄露
Handler对象隐性地持有了Activity的对象,当发生GC时因为 message – handler – acitivity 的引用链导致Activity无法被回收,所以发生了内存泄露的问题。
二、原因是什么
Handler对象隐性地持有了Activity的对象,说的更加深入一点就是内部类持有外部类的引用。
参考:https://www.cnblogs.com/punkisnotdead/p/4943260.html
三、解决方案
更改的方法也很简单,那就是直接把这个内部类 改成静态的不就行了!
private static class MyHandler extends Handler
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
}
private MyHandler myHandler=new MyHandler();
那,又有人要问了,你这个静态类,不讲道理啊,我要引用activity的属性 比如textview 啥的,引用不了啊,总不能textview 还让我弄成static变量吧,那其实这边还是有解决方法的。
private TextView tv;
private static class MyHandler extends Handler
{
private final WeakReference<MainActivity> mActivity;
@Override
public void handleMessage(Message msg) {
MainActivity activity=mActivity.get();
if (null!=activity)
{
activity.tv.setTag("123");
super.handleMessage(msg);
}
}
public MyHandler(MainActivity mainActivity)
{
this.mActivity=new WeakReference<MainActivity>(mainActivity);
}
}
private MyHandler myHandler=new MyHandler(MainActivity.this);
为什么要用弱引用,我解释一下,当我们activity被弹出栈以后,此时就没有强引用去指向这个activity对象了。
如果发生gc,这个activity就会被回收,activity持有的那些资源也自然而然就烟消云散了。对于dalivk虚拟机来说,第一次gc的时候是会把没有任何引用的对象和只有弱引用的对象全部回收掉的,只有当发现这2种对象全部回收掉以后所剩下的内存依然不够,那此时就会再进行一次gc,这时候gc会把软引用指向的对象也回收掉。所以这里用弱引用是最合适的。
你看 如果handler不做这种处理的话,我们gc的时候,一看,诶,怎么还有一个对象(handler的对象)持有activity的引用,恩,还是不销毁了。。。所以就内存泄露了。
网友评论