文档章节

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

SuShine
 SuShine
发布于 2015/06/23 09:24
字数 947
阅读 38
收藏 0
点赞 0
评论 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
粉丝 118
博文 435
码字总数 88625
作品 0
青岛
后端工程师
C可执行文件的内存结构

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

Jeff_Linux ⋅ 2014/07/19 ⋅ 0

Java中数据存储方式

1.寄存器(register)。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程...

gavin_jin ⋅ 2012/02/03 ⋅ 0

C语言局部变量和全局变量问题汇总

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

graylee ⋅ 2013/10/28 ⋅ 0

一种Android应用内全局获取Context实例的装置

哥白尼·罗斯福·马丁路德·李开复·嫁衣曾经说过 Where there is an Android App, there is an Application context. 没毛病,扎心了。App运行的时候,肯定是存在至少一个Application实例的...

Kaede ⋅ 2017/04/10 ⋅ 0

Objective-C笔记

1、在编译一个使用了CPerson类的文件时,如果不需要知道该类的全部细节,只需要知道有一个类名叫CPerson,最好“向前声明”该类(同理于对一个协议的引用),这样做也可以避免“循环引用”问...

_子墨 ⋅ 2015/12/22 ⋅ 0

static的用法

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

shenlongfuhuo ⋅ 2014/04/21 ⋅ 0

Linux下C程序进程地址空间布局

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

zhangyujsj ⋅ 2014/04/11 ⋅ 0

Android中Application类用法

1.应用场景:   在Android中,可以通过继承Application类来实现应用程序级的全局变量,这种全局变量方法相对静态类更有保障,直到应用的所有Activity全部被destory掉之后才会被释放掉。 2....

一别经年 ⋅ 2014/01/21 ⋅ 0

application 的用法

Application类 Application和Activity,Service一样是Android框架的一个系统组件,当Android程序启动时系统会创建一个Application对象,用来存储系统的一些信息。 Android系统自动会为每个程序...

MOMOLIN ⋅ 2016/04/07 ⋅ 0

java final和static用法总结

Java关键字final、static使用总结 一、final 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理...

艾柯 ⋅ 2014/03/12 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vim介绍、vim颜色显示和移动光标、vim一般模式下移动光标、一般模式下复制粘贴剪切

VIM Vim 是 UNIX 文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff),语法高亮,全面的帮助系统,本地脚本(Vimscript),和便于选择的...

蛋黄Yolks ⋅ 15分钟前 ⋅ 0

springboot+mockito测试controller层遇到的问题

使用MockitoJUnitRunner测试的一个例子,原来报错无法找到bean, 类似的异常如下:createBeanError..... 原因:是因为@Runwith使用了SpringRunner,应该修改为MockitoJUnitRunner 代码如下: ...

writeademo ⋅ 27分钟前 ⋅ 0

关于“幂等”操作

一个幂等(idempotent)操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同. 开发中, 我们经常考虑幂等操作的场景有“接口调用”、“MQ消费”、“自动任务”等 接口调用, 可能出现...

零二一七 ⋅ 34分钟前 ⋅ 0

Dubbo服务服务暴露之ProxyFactory Invoker

Dubbo服务暴露过程中有涉及到调用ProxyFactory 中方法获取Invoker对象的过程,现在我们来深究下源码,来看下这个过程是在做些什么,返回的Invoker 对象是什么,我们来看一下代码的切入点: ...

哲别0 ⋅ 49分钟前 ⋅ 0

GP两种连接方式性能测试

GP两种连接方式性能测试 Pivotal import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class GPQueryStrin......

仔仔1993 ⋅ 53分钟前 ⋅ 0

jsonrpc-4j代码解析

解析文件 AutoJsonRpcServiceImplExporter JsonServiceExporter AutoJsonRpcServiceImplExporter 路径:com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter AutoJsonRpcServi......

郭恩洲_OSC博客 ⋅ 今天 ⋅ 0

百度搜索

from selenium import webdriver import time brower=webdriver.Firefox() brower.get('http://www.baidu.com') input=brower.find_element_by_id('kw') input.send_keys('中南大学') time.s......

南桥北木 ⋅ 今天 ⋅ 0

tomcat 日志记录器

1、日志记录器是记录消息的组件 日志记录器需要与某个servlet 容器相关联 2、Logger 接口 共定义了5种日志级别:FATAL、ERROR、WARNING、INFORMATION、DEBUGGER setVerbosity 设置级别 setC...

职业搬砖20年 ⋅ 今天 ⋅ 0

Thrift RPC实战(三) Thrift序列化机制

1.Thrift基础架构 Thrift是一个客户端和服务端的架构体系,数据通过socket传输; 具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports); 通过IDL脚本对传输数据的数据结构...

lemonLove ⋅ 今天 ⋅ 0

网站建设就要像2018世界杯的俄罗斯队大杀四方[图]

今天心情不错,因为昨天晚上观看了世界杯比赛,尤其是对俄罗斯队的大杀四方感到十分霸气侧漏啊,因此我联想到了自己的博客网站,我的博客是去年年底上线的,一直想建设一个关于读书和读后感作...

原创小博客 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部