内存泄漏之activitiy被单例绑定

public class LoginManager {

private Context context;
private static LoginManager manager;

public static LoginManager getInstance(Context context) {
    if (manager == null)
        manager = new LoginManager(context);
    return manager;
}

private LoginManager(Context context) {
    this.context = context;
}

在LoginActivity中

public class LoginActivity extends Activity {

private LoginManager loginManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    loginManager = LoginManager.getInstance(this);
}

这种方式大家应该一看就明白问题在哪里了,在LoginManager的单例中context持有了LoginActivity的this对象,即使登录成功后我们跳转到了其他Activity页面,LoginActivity的对象仍然得不到回收因为他被单例所持有,而单例的生命周期是同Application保持一致的。

正确的获取context的方式

public class LoginManager {

private Context context;
private static LoginManager manager;

public static LoginManager getInstance(Context context) {
    if (manager == null)
        manager = new LoginManager(context);
    return manager;
}

private LoginManager(Context context) {
    this.context = context.getApplicationContext();
}

修改方式也非常简单我们单例中context不再持有Activity的context而是持有Application的context即可,因为Application本来就是单例,所以这样就不会存在内存泄漏的的现象了。
单例模式中通过内部类持有activity对象

第一种方式内存泄漏太过与明显,相信大家都不会犯这种错误,接下来要介绍的这种泄漏方式会比较不那么容易发现,内部类的使用造成activity对象被单例持有。

还是看代码再分析,下面是一个单例的类:

public class TestManager {
public static final TestManager INSTANCE = new TestManager();
private List mListenerList;

private TestManager() {
    mListenerList = new ArrayList<MyListener>();
}

public static TestManager getInstance() {
    return INSTANCE;
}

public void registerListener(MyListener listener) {
    if (!mListenerList.contains(listener)) {
        mListenerList.add(listener);
    }
}
public void unregisterListener(MyListener listener) {
    mListenerList.remove(listener);
}

}

interface MyListener {
public void onSomeThingHappen();
}

然后是activity:

public class TestActivity extends AppCompatActivity {

private MyListener mMyListener=new MyListener() {
    @Override
    public void onSomeThingHappen() {
    }
};
private TestManager testManager=TestManager.getInstance();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    testManager.registerListener(mMyListener);
}

}

 我们知道在java中,非静态的内部类的对象都是会持有指向外部类对象的引用的,因此我们将内部类对象mMyListener让单例所持有时,由于mMyListener引用了我们的activity对象,因此造成activity对象也不能被回收了,从而出现内存泄漏现象。

修改以上代码,避免内存泄漏,在activity中添加以下代码:`

@Override
protected void onDestroy() {
testManager.unregisterListener(mMyListener);
super.onDestroy();
}
AsyncTask不正确使用造成的内存泄漏

介绍完以上两种情况的内存泄漏后,我们在来看一种更加容易被忽略的内存泄漏现象,对于AsyncTask不正确使用造成内存泄漏的问题。

mTask=new AsyncTask

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值