您的位置:首页 > 移动开发

在单例模式中如何避免传入非Application的Context造成的内存泄漏

2016-09-15 16:51 531 查看
下面我们先来看一个非常常见的单例模式:

public class GCSingleTon{
private static GCSingleTon singleTon;
private Context context;

private GCSingleTon(Context context){

this.context=context;

}

public static GCSingleTon getSingleTon(Context context){
if (singleTon==null){
singleTon=new GCSingleTon(context);
}
return singleTon;
}
}


接着我们来分析这个非常简单的单例模式:

如果此时传入的是Application的Context,没问题;但是如果传入非Application的context例如:Activity的context,由于此context为单例模式持有,那么它的生命周期就会和程序的生命周期一样长, 就会造成此Activity退出销毁却没有被回收,造成严重的内存泄漏;

那么如何避免 呢:方法很简单,那就是不用Activity的context而直接用Application的context.下面我们来看代码:

public class GCSingleTon{
private static GCSingleTon singleTon;
private Context context;

private GCSingleTon(Context context){
//正确的写法是
this.context=context.getApplicationContext();
}

public static GCSingleTon getSingleTon(Context context){
if (singleTon==null){
singleTon=new GCSingleTon(context);
}
return singleTon;
}
}


很多小伙伴看到这里不禁要吐槽了吧,既然要用Application的context,那为何要费力拔插地传入Activity的context然后再调用Activity的context来获得Application的context呢,而不在Application 中添加一个静态方法,返回 Application 的 context.

对啊,Why not?既然有了这个想法我们就一起来试试吧,见代码:

public class MyApplication extends Application {

static Context context;

public static Context getContext() {

return context;

}

@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
}


这样当然没问题,需要注意的是静态方法中不能掉用非静态变量和方法!所以context的初始化方法要放在onCreate()中.不过这都是常识,我也是白嘱咐这么一句!

那么接下来单例模式就简单了,连Context参数都不用传了.见代码:

private GCSingleTon(){
context=MyApplication.getContext();
}

public static GCSingleTon getSingleTon(){
if (singleTon==null){
singleTon=new GCSingleTon();
}
return singleTon;
}


是不是看着用着都舒服多了?!

That is all.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: