文档章节

不要通过Application Object或者其他全局静态变量来存放数据

SuShine
 SuShine
发布于 2015/06/23 09:24
字数 947
阅读 38
收藏 0

           不要通过Application Object或者其他全局静态变量来存放数据

 

    转载请注明来自:http://blog.csdn.net/liaoqianchuan00/article/details/24399093

翻译自:http://www.developerphil.com/dont-store-data-in-the-application-object/

 

概述

在我们的应用程序中,很多地方可能用到同一个数据。很多时候我们可能不想通过Intent在Activity之间传递或者持久化的存放这些数据来。

 

我们可能会将这些数据存放在Application对象中,这样我们就可以在所有的Activity中访问了。这个方法很简单,但是实际上是完全错误的。

 

你的程序可能会因为NullPointerException而crash掉,因为上面的方案是基于你假设你存放的数据一直都在那里的。

 

例子

Application对象:

 

// access modifiers omitted for brevity

class MyApplication extends Application {

 

    String name;

 

    String getName() {

        returnname;

    }

 

    void setName(String name) {

        this.name= name;

    }

}

 

在第一个Activity中,我们将一个用户的名字存放在Application中:

 

// access modifiers omitted for brevity

class WhatIsYourNameActivity extends Activity {

 

    void onCreate(BundlesavedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.writing);

 

        //Just assume that in the real app we would really ask it!

        MyApplicationapp = (MyApplication) getApplication();

        app.setName("DeveloperPhil");

        startActivity(newIntent(this, GreetLoudlyActivity.class));

 

    }

 

}

 

在第二个Activity中,我们取出这个用户的名字:

 

// access modifiers omitted for brevity

class GreetLoudlyActivity extends Activity {

 

    TextView textview;

 

    void onCreate(BundlesavedInstanceState) {

        super.onCreate(savedInstanceState);

 

        setContentView(R.layout.reading);

        textview= (TextView) findViewById(R.id.message);

    }

 

    void onResume() {

        super.onResume();

 

        MyApplicationapp = (MyApplication) getApplication();

        textview.setText("HELLO" + app.getName().toUpperCase());

    }

}

 

场景

1.       用户打开程序。

2.       在WhatIsYourNameActivity中,你询问用户的名字,并且把它存放到Application中。

3.       在GreetLoudlyActivity中,你从MyApplication对象中取出用户的名字并且显示。

4.       用户按Home键离开我们的应用程序。

5.       数小时后,Android系统可能杀掉你的程序来获得更多的内存。

到现在为止,看起来都很正常。但是Crash马上就要发生了。

6.       用户重新打开程序。

7.       Android建立一个新的MyApplication实例,并且重新恢复GreetLoudlyActivity。

8.       GreetLoudlyActivity取得用户的名字,但是现在已经是null了,然后报错NullPointerException。

 

为什么会Crash?

在这个例子中,因为Application实例是重新创建的,所以name变量是null,导致我们在调用String->toUpperCase的时候报NullPointerException。

 

这就将我们引向了核心问题:Application对象不会一直在内存中存在,他可能被杀掉。和我们认为的相反,他不会恢复以前的信息。Android会创建一个新的Application对象,然后重新打开之前用户按Home离开的那个Activity。

 

这就是说,如果你假设Activity B不可能在Activity A之前开启,所以你保存数据在Application中,那么你的程序可能就会crash。

 

解决方案

1.       通过Intent在Activity之间传递数据。

2.       使用多种持久化保存数据的方式(文件,数据库,sharedpreference等)。

3.       做null判断,并且手动处理null的情况。

 

如何模拟应用程序被杀掉

1.       按Home键离开你的应用程序

2.       打开DDMS,选中你应用程序的进程,点击“stop process”。

3.       使用task switcher返回你的应用程序。现在你的应用程序的Application对象就是一个新的实例了。

 

总结

在Application对象中保存数据室错误的并且可能导致你的程序crash,使用Intent来传递数据或者将数据保存在disk上。

 

同时记住,这个问题同样适用于任何单例或者公共的静态变量。

 

 

备注:  在实际项目中却还是使用到了单例和静态变量, 所以可能导致后台很长时间之后崩溃, 现在的解决方案是

保存在Activity的成员变量 应该用 onsave存起来 单例 应该在i()中进行一次初始化

或者在 oncreate 重新初始化.

 

 

本文转载自:http://blog.csdn.net/liaoqianchuan00/article/details/24399093

共有 人打赏支持
SuShine
粉丝 124
博文 538
码字总数 153323
作品 0
朝阳
后端工程师
私信 提问
C可执行文件的内存结构

以前看过C可执行文件的内存结构,但都只是当时很清楚,时候就忘的差不多了,没有细细去品味,一段时间就忘得差不多了,今天看了一些书籍和博文,决定将C可执行文件的内存结构的内容通过博客记...

Jeff_Linux
2014/07/19
0
0
static的用法

一、定义全局静态变量的好处: <1>不会被其他文件所访问,修改 <2>其他文件中可以使用相同名字的变量,不会发生冲突。 2. 局部静态变量 在局部变量之前加上关键字static,局部变量就被定义成...

shenlongfuhuo
2014/04/21
0
0
C语言局部变量和全局变量问题汇总

1、局部变量能否和全局变量重名? 答:能,局部会屏蔽全局。要用全局变量,需要使用"::" 局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。...

graylee
2013/10/28
0
0
全局变量和局部变量在内存里的区别 .

============================================================== static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?...

Sophia_tj
2012/09/13
0
0
Linux下C程序进程地址空间布局

我们在学习C程序开发时经常会遇到一些概念:代码段、数据段、BSS段(Block Started by Symbol) 、堆(heap)和栈(stack)。先看一张教材上的示意图(来源,《UNIX环境高级编程》一书),显...

zhangyujsj
2014/04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sed插入和附加文本基础使用

对于编辑器来说,在数据中增加行算是很基本的操作吧,sed有以下两个操作: 插入(insert)命令(i)会在指定行前增加一个新行 附加(append)命令(a)会在指定行后增加一个新行 还是用下面的文本来测...

woshixin
6分钟前
0
0
HIVE数据倾斜总结

在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显。主要是因为在Job完成后的所得到的Counters是整个Job的总和,优化是基于这些Counters得出的平均值,...

瑞查德-Jack
17分钟前
0
0
Pure-ftpd搭建FTP

12月11日任务 15.4 xshell使用xftp传输文件 15.5 使用pure-ftpd搭建ftp服务 使用pure-ftpd搭建FTP服务 轻量的ftp软件 安装pure-ftpd并修改配置文件 # pure-ftpd为epel扩展库里的软件[root...

robertt15
26分钟前
3
0
开源 serverless 产品原理剖析(二) - Fission

背景 本文是开源 serverless 产品原理剖析系列文章的第二篇,关于 serverless 背景知识的介绍可参考文章开源 serverless 产品原理剖析(一) - Kubeless,这里不再赘述。 Fission 简介 Fiss...

阿里云官方博客
33分钟前
2
0
Android面试整理(附答案)

面试,无非都是问上面这些问题(挺多的 - -!),聘请中高级的安卓开发会往深的去问,并且会问一延伸二。以下我先提出几点重点,是面试官基本必问的问题,请一定要去了解! 基础知识 – 四大组...

终端研发部
37分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部