Android应用之——不要将数据存储在Application类中

前言:最近在开发中发现了一个比较严重的问题,当我们将应用按home键放入后台运行,一段时间后,当我们再次打开应用的时候,十有八九会出现一个NullPointException的空指针异常,根据logcat的日志,就会定位到一个去全局性到变量去,这是什么原因呢?原来,是因为我们我们将很多数据放入了application中作为全局变量,导致了问题的产生,下面来说下为什么不能将数据放在application中。


一、application类的简介
Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。一般情况下,系统会默认帮我们创建一个application类,我们不需要在其中进行任何操作,程序会自动创建。当如果需要创建自己的Application,在其中进行一些操作,也很简单,创建一个类继承 Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。
[html]  view plain copy print ?
  1. <application  
  2.        android:name="com.example.applicationdemo.MyApplication"  
  3.        android:allowBackup="true"  
  4.        android:icon="@drawable/ic_launcher"  
  5.        android:label="@string/app_name"  
  6.        android:theme="@style/AppTheme" >  
其中My Application类就是我们自定义的一个类,继承自Application类
[java]  view plain copy print ?
  1. public class MyApplication extends Application {      
  2.     public String name;  
  3.     public String getName() {  
  4.         return name;  
  5.     }  
  6.   
  7.     public void setName(String name) {  
  8.         this.name = name;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void onCreate() {  
  13.         // TODO Auto-generated method stub  
  14.         super.onCreate();  
  15.     }     
  16. }  

二、application中为什么不能存储数据
下面我们来看一个简单的示例:
我们在application继承类中写一个set get变量的方法,然后通过第一个activity利用application的set方法来设置这个变量的值,在另一个activity中取得这个值,并将其转换为大写显示出来。代码如下:
MainActivity:
[java]  view plain copy print ?
  1. public class MainActivity extends Activity {  
  2.   
  3.     private MyApplication application;  
  4.     private Button btnName;  
  5.   
  6.     @Override  
  7.     protected void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.activity_main);  
  10.         application = (MyApplication) getApplication();  
  11.         application.setName("YangLiang");  
  12.           
  13.         btnName = (Button) findViewById(R.id.btn_name);  
  14.           
  15.         btnName.setOnClickListener(new OnClickListener() {  
  16.             @Override  
  17.             public void onClick(View v) {  
  18.                 Intent intent = new Intent(MainActivity.this, ShowNameActivity.class);  
  19.                 startActivity(intent);  
  20.             }  
  21.         });  
  22.           
  23.     }  
  24. }  
MyApplication类
[java]  view plain copy print ?
  1. public class MyApplication extends Application {  
  2.     public String name;  
  3.     public String getName() {  
  4.         return name;  
  5.     }  
  6.   
  7.     public void setName(String name) {  
  8.         this.name = name;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void onCreate() {  
  13.         // TODO Auto-generated method stub  
  14.         super.onCreate();  
  15.     }  
  16. }  
另一个activity,显示内容
[java]  view plain copy print ?
  1. public class ShowNameActivity extends Activity {  
  2.   
  3.     private MyApplication app;  
  4.     private TextView tv;  
  5.   
  6.     @Override  
  7.     protected void onCreate(Bundle savedInstanceState) {  
  8.         // TODO Auto-generated method stub  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.showname);  
  11.         app = (MyApplication) getApplication();  
  12.         String name = app.getName();  
  13.         tv = (TextView) findViewById(R.id.tv_showname);  
  14.         tv.setText(name.toLowerCase());  
  15.     }  
  16.       
  17. }  
打开应用后,进入ShowNameActivity界面中,然后按home键进入后台,一段时间后,再次打开demo,就出现了空指针异常

logcat中的错误日志

定位到了这句代码:
[java]  view plain copy print ?
  1. tv.setText(name.toLowerCase());  
name在这个时候已经为空了

这是什么原因呢?
因为当应用程序在后台运行的时候,当我们将应用程序切入到后台或者当内存不足时,系统可能会将当前应用的application进程干掉,
当我们再次从后台将应用切换到前台的时候,系统会重新生成一个application类,这个时候,我们在显示的activity中调用
[java]  view plain copy print ?
  1. app = (MyApplication) getApplication();  
  2. String name = app.getName();  
  3. tv.setText(name.toLowerCase());  
上面的name就是空的,因此会出现空指针异常,也就是说,我们存储在application中的数据,有可能会因为程序运行在后台的时候导致application的销毁和重建进而导致数据的丢失,这对于程序来说是致命的,直接导致空指针异常的出现,程序崩溃。


三、有什么更好的办法?
1、通过intent来传递数据,而不是将数据放在全局变量application中,当然这么做是有局限性的,并不是所有地方都适合用intent来传递数据,也并不是所有类型的数据都适合用intent来传递,关于intent的数据传递,读者可参考其他资料。

2、将数据进行持久化操作,写入文件,shareprefrence,数据库等等各种能够安全保存数据的方法。然后在需要使用数据的地方进行文件读取操作。

3、在所有需要使用此类数据的地方进行非空的判断,然后进行相应的操作。

四、总结:不要轻易在application类中进行数据的存储操作,application类中应当做的是进行一些全局性的配置的初始化操作,而数据的存储应该使用前面推荐的几种方法。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值