Android中的Application对象里尽量不要存储数据

问题:

在做一个项目的时候需要将登陆后后台返回的数据进行保存,然后再其他地方调用。

解决方案:

公司中的一个员工是这样处理的
在MyApplication中定义了一个User user = new User();(保存数据的对象),然后再获取到数据的时候,将获取到的数据直接赋值给这个对象(MyApplication.user = userTest;)然后在其他地方用的时候就直接用MyApplication.user.get……然后获取其中需要用的数据,这种方法可行吗?显然是不可行的,因为MyApplication.user = user;只是将MyApplication.user指向了userTest的地址,并没有真正的将User中的属性值赋值到MyApplication.user中,当userTest因为内存不足而被干掉的时候那MyApplication.user指向的就是个空了啊,所以这样也肯定是不行的。

后来我想尝试是不是可以通过对象克隆将真个对象复制到MyApplication的user中,后来我放弃了因为Object中的clone方法是protected的如果重写这个方法也只能是复制了一个对象,但是在向MyApplication.user赋值的时候还是指向,而不是将其中的所有属性值全部赋值上去。
具体对象复制可以参照
http://blog.csdn.net/u013802387/article/details/78272713

所以如果真的想在MyApplication中保存这个user那就必须在获取数据之后,自己手动的将所有的属性值一个一个的set上去。这种方法能解决这个问题,但是过于麻烦,如果是因为想将数据保存到内存中使读取速度更快的话个人感觉真的没这个必要,而且如果是保存在Application中的话会有一些意想不到的问题。

测试如下

  1. 用户启动app。

  2. 在 第一个Activity里面,要求用户输入姓名,并存储到 MyApplication

  3. 在 第二个Activity里面,你从MyApplication 对象中获得用户姓名,并且显示。

  4. 用户按home键离开这个app。

  5. 几个小时后,Android系统为了回收内存kill掉了这个app。到目前为止,一切尚好。接下来就是crash的部分了…

  6. 用户重新打开这个App。

  7. Android系统创建一个新的 MyApplication 实例并恢复 第二个Activity

  8. 第二个Activity从新的 MyApplication 实例中获取用户姓名,可得到的为空,最后导致NullPointerException。

为什么会Crash?

在上面这个例子中,app会crash得原因是这个 Application 对象是全新的,所以这个name 变量里面的值为 null,当调用String#toUpperCase() 方法时就导致了NullPointerException。

整个问题的核心在于:application 对象不会一直呆着内存里面,它会被kill掉。与大家普遍的看法不同之处在于,实际上app不会重新开始启动。Android系统会创建一个新的 Application 对象,然后启动上次用户离开时的activity以造成这个app从来没有被kill掉得假象。

你以为你的application可以保存数据,却没想到你的用户在没有打开activity A 之前就就直接打开了 activity B ,于是你就收到了一个 crash 的 surprise。

总结

不要在application对象里面储存数据,这容易出错,导致你的app crash。
要么将你后面要用的数据保存到磁盘上面或者保存到intent得extra里面直接传递给activity 。

这些结论不但对application对象有用,对你app里面的单例对象(singleton)或者公共静态变量(public static)同样适用。

最后解决方案

最后我将登陆时候获取的数据对象实现Serializable,然后将其转化为字节,最后用Base64.encode将字节文件转换成Base64编码保存在String中当需要用到的时候将String数据取出将其解码然后强制转换成自己想用的对象即可,具体实现方法如下:

http://blog.csdn.net/u013802387/article/details/78272487

猜你喜欢

转载自blog.csdn.net/u013802387/article/details/78655503