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中使用单例模式呢?希望有好方法的同学能分享自己的看法~

时间: 2024-10-13 07:10:15

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

android在单身的对象和一些数据的问题被释放

正式接触android我们一直在开发了一段时间,该项目的第一个版本最终会很快结束. 当有它自己的测试.拥有android后台.同一时候打开了几个应用之后又一次切回到自己的app.发现报错了.经过排查,发现是自己的单例对象中的数据被释放掉了,也就是int变量的值 变成了0,string变量的值变成了null. 我的单例一開始是这种(举例); public class UserInfo { private static UserInfo userInfo = null; private int le

单例对象

在开发中经常需要使用单例对象.今天主要说的是单例宏 首先先简单介绍一下 1.单例设计模式(Singleton) 1> 什么: 它可以保证某个类创建出来的对象永远只有1个 2> 作用(为什么要用) * 节省内存开销 * 如果有一些数据, 整个程序中都用得上, 只需要使用同一份资源(保证大家访问的数据是相同的,一致的) * 一般来说, 工具类设计为单例模式比较合适 3> 怎么实现 * MRC(非ARC) * ARC 代码采用的是mrc的环境 单独创建一个.h文件 例如SingleTon.h

010-Scala单例对象、伴生对象实战详解

010-Scala单例对象.伴生对象实战详解 Scala单例对象详解 函数的最后一行是返回值 子项目 Scala伴生对象代码实战 object对象的私有成员可以直接被class伴生类访问,但是不可以被其他的类或者对象访问 伴生类访问伴生对象的成员时,要通过名称.成员来访问 调用一些元素的方法初始化创建的时候,例如:Array(1,2,,34,5,6)其实调用了它的apply()方法 欢迎广大爱好者学习交流.也欢迎广大学习爱好者加入 DT大数据梦工厂交流群:462923555 DT大数据微信公众账

探索Scala(3)-- 单例对象

研究一下Scala语言的单例对象(Singleton Objects),为下一篇文章做准备. static不是关键字 上一篇文章提到过,interface并不是Scala语言关键字,可以自由使用.同样,static在Scala里也没有特殊的含义,也是可以自由使用的,如下面代码所示: 单例对象 Java并不是完美的面向对象语言,包括很多缺陷,比如允许static字段和方法,primitive类型,等等.Scala语言在这些方面都有所改进,所以号称是比Java更OO的语言.既然去掉了static关键

scala学习手记14 - 单例对象

java中的单例模式都很熟悉了:简单地说就是一个类只能有一个实例.在scala中创建单例对象非常简单,创建类时使用object关键字替换class即可.因为单例类无法初始化,所以不能向它的主构造函数传递参数. 下面是一个单例的示例: class Marker(val color: String) { println("Creating " + this) override def toString(): String = "marker color " + colo

iOS:创建单例对象的两种方式

单例模式:创建单例对象的两种方式 方式一:iOS4版本之前 static SingleClassManager *singleManager = nil; +(SingleClassManager*)sharedManager { @synchronized(self)  //同步加锁,在多线程中使用,可以使线程安全 { if(singleManager == nil) { singleManager = [[SingleClassManager alloc]init]; } } return

Scala的单例对象

通常,一个类对应一个伴生对象,其方法就跟Java中的静态方法一样,举例:BigInt类的BigInt伴生对象有一个生成指定位数的随机素数的方法probablePrime,在REPL中运行下列代码: object HelloWorld{ def main(args:Array[String]){ for( i<- 1 to 10){ println(BigInt.probablePrime(10,scala.util.Random)); } } } 得到的结果如下: 523 977 839 911

atitit.guice3&#160;绑定方式打总结生成非单例对象toInstance&#160;toProvider区别&#160;v2&#160;pb29

atitit.guice3 绑定方式打总结生成非单例对象toInstance toProvider区别 v2 pb29 1. 三 绑定方式的介绍1 2. To接口,链式绑定,用的最多的1 3. toConstructor1 4. toInstance生成的都是单例对象的...3 5. toProvider生成非单例对象3 5.2. 注解(Annotations)绑定3 5.3. 实例绑定(str,int绑定)4 5.4. 无目标绑定4 6. 参考5 重大的描述 1. 三 绑定方式的介绍 1. 在

【cocos2d-js官方文档】二十五、Cocos2d-JS v3.0中的单例对象

为何将单例模式移除 在Cocos2d-JS v3.0之前.全部API差点儿都是从Cocos2d-x中移植过来的,这是Cocos2d生态圈统一性的重要一环.可惜的是,这样的统一性也在非常大程度上限制了Cocos2d-html5的发展,有一些在C++中非常有意义的涉及搬到Html5平台后却使得Cocos2d-html5变得臃肿.所以在3.0版中,我们决定将一些API改造成更适合JavaScript开发者的API.这篇文档中将要展示的是单例类的改造. 拿cc.SpriteFrameCache为例: /