android里单例对象和某些数据被释放的问题

接触正式的android开发已经有一段时间了,项目的第一个版本终于快完成了。有一次自己在测试的时候,把自己的android项目切到后台,同时打开了几个应用之后重新切回到自己的app,发现报错了。经过排查,发现是自己的单例对象中的数据被释放掉了,也就是int变量的值 变成了0,string变量的值变成了null。

    我的单例一开始是这样的(举例);

    

public class UserInfo {
	private static UserInfo userInfo = null;
	
	private int level;
	
	private UserInfo() {  
		
    <span style="white-space:pre">	</span>}
	
	public static UserInfo getInstance() {
		if (null == userInfo) {
			userInfo = new UserInfo();
		}
		return userInfo;
	}
	
	public void setLevel(int level){
		this.level = level;
	}
	
	public int getLevel(){
		return level;
	}
}

      这应该是一个比较普通的单例类,用来存储我们经常使用的变量,平时我的使用是没有问题的,在各个activity,fragment里都可以正常使用,如下面代码片段:

if(UserInfo.getInstance().getLevel() == 3){
	//我们的代码块
}


但是,当我使用我的测试机(测试机是512m内存)进行测试的时候,首先把android应用切到后台,打开多个其他的app如qq等,再把我们的应用恢复到前台的时候,上面例子的代码块竟然没有进入,我通过打印调试发现getLevel()的值已经是0了,也就是被释放了。我google了一下,有些人在android上使用像我这样的单例是没问题的,而有些人则会说自己的单例被释放了,也就是和我的情况一样。可能是由于手机内存吃紧,我们单例对象存储的数据被迫被释放了。

下面就要找到这个问题的解决方法。

(1)使用android application ,这个方法本来我是想使用的,但是大概查了一下,例如这篇文章:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0204/2409.html

发现最好不要使用这种方法,甚至文章里写了都不要使用单例~~我自己试了一下,感觉问题依然存在。

(2)onSaveInstanceState() 和 onRestoreInstanceState(),当我发生这个问题的时候,都是android强制性的移除了我当前的activity,可能同时释放了我的单例对象中的数据。我也的确执行了onSaveInstanceState()函数,同时在切回来的时候执行了onRestoreInstanceState()重绘我的activity,那么我可以在onSaveInstanceState() 里存储我的单例数据,然后在onRestoreInstanceState()里对我的数据进行重新赋值。这样貌似也是可以的,但是,这样的话,单例用起来就太那啥了,感觉都不需要单例了。。

(3)使用SharedPreferences来进行存取数据的操作,当我们为数据赋值和取出数据的时候,不妨用下面的代码:

<span style="white-space:pre">	</span>public void setLevel(int level, Context context){
		saveSharedPreferences(context, "level", level+"");
		this.level = level;
	}
	
	public int getLevel(Context context){
		level = Integer.parseInt(Utils.readSharedPreferences(context, "level"));
		return level;
	}
<span style="white-space:pre">	</span>public static void saveSharedPreferences(Context context, String name, String data) {
		SharedPreferences sharedPreferences = context.getSharedPreferences("school_user_info", Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = sharedPreferences.edit();
		editor.putString(name, data);
		editor.commit();
	}

	public static String readSharedPreferences(Context context, String name) {
		SharedPreferences sharedPreferences = context.getSharedPreferences("school_user_info", Context.MODE_MULTI_PROCESS);
		return sharedPreferences.getString(name, "");
	}


在为单例对象中的数据赋值的时候,把这个数据存放在preference中,使用的时候,再从preference中取出我的值,进行相应的操作,这样做的话,即使当我的单例被释放了,我依旧可以从preference中取出数据,这样做之后,我发现自己之前的bug就消失了,不会因为数据为空导致各种各样的错误了。

但是,仔细想一下,发现这样做的话单例模式在这里使用就略有多余,我直接存取preference就可以了,干嘛还要这样写呢?因为项目进度较为紧迫,我只好用(3)方法修改了一下我的代码保证了其没有这样的bug,但是这样做以我现在的眼光来看,并不是非常好,感觉造成了代码的多余。但是单例模式是我们工作中最常用到的设计模式了,在学校的时候我们就经常使用它,难道在android里就不能这样使用单例吗?我对此持怀疑态度。

不知道大家有没有遇到和我一样的问题,如果遇到了,又是如何解决的呢?该如何在android中使用单例模式呢?希望有好方法的同学能分享自己的看法~

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。