不要在Application保存数据
引言:
总是有需要在很多地方在你的应用程序的一些信息。它可以是一个会话,一个昂贵的计算的结果,等,它通常是很诱人的让你避免Activity之间传递对象或保持那些在持久存储的开销。
有时候建议这个模式,这将是可用在所有Activity的Application对象。这个解决方案很简单,优雅......然后这个模式是完全错误的。
如果你认为你的数据将放在那里,那么你的应用程序将最终与一个NullPointerException异常崩溃
一个简单的案例:
The Application object:
class MyApplication extends Application { String name; String getName() { return name; } void setName(String name) { this.name = name; } }
第一个Activity,在那里我们把用户的名称存储在Application对象中:
class WhatIsYourNameActivity extends Activity { void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.writing); MyApplication app = (MyApplication) getApplication(); app.setName("Developer Phil"); startActivity(new Intent(this, GreetLoudlyActivity.class)); } }
第二个Activity,我们读取用户的名称
class GreetLoudlyActivity extends Activity { TextView textview; void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.reading); textview = (TextView) findViewById(R.id.message); } void onResume() { super.onResume(); MyApplication app = (MyApplication) getApplication(); textview.setText("HELLO " + app.getName().toUpperCase()); } }
操作流程:
1.开启Application对象
2.在WhatIsYourNameActivity中你保存一个用户名称并且保存到Application对象中
3.在GreetLoudlyActivity你读取用户名称并且显示出来
4.使用HOME键离开程序
5.一段时间后,Android将静静杀死这个程序去回收内存
到目前为止,一切都很好!
这里会有一个意外
6.用户重新打开应用程序
7.Android的创建一个新的MyApplication的实例,并恢复GreetLoudlyActivity
8.GreetLoudlyActivity获取用户名,但是现在是NULL,程序崩溃并且跑出一个NullPointerException异常
为什么会有这个意外呢?
在这个案例中。程序意外崩溃是因为Application是一个全新的对象,所以我们获取名称变量是NULL的,所以当我们调用String#toUpperCase()的时候导致程序抛出NullPointerException异常
这给我们带来了问题的核心:Application不会永远留驻,它会被杀死。这个程序将不会恢复到原来的状态。Android将为程序重新创建一个Application对象并且开启Activity给用户一种Application从未被杀死的现象
这意味着。如果只是你的用户不想在Activity A中打开一个Activity B而将一些数据保存到Application中。那么你将会得到这样一个意外的惊喜(NPE)
那么有什么办法解决?
有没有神奇的解决方案,在这里,您可以执行下列操作之一:
1.通过Intent明确的传递数据到Activity
2.将数据持久化到磁盘上
3.总是进行非空检查并作出对应的处理
如何模拟Application被杀死?
一个简单的方法来杀你的应用程序, 在DDMS中,使用“Stop Process”功能(红色Stop图标)
为了模拟这个现象。你必须使用模拟器或者使用一个root过的手机
1.使用HOME键退出你的程序
2.在终端:
# 查找你的进程ID adb shell ps # 找到你应用程序的包名 # Mac/Unix: save some time by using grep: adb shell ps | grep your.app.package # 查找结果如下 # USER PID PPID VSIZE RSS WCHAN PC NAME # u0_a198 21997 160 827940 22064 ffffffff 00000000 S your.app.package #通过PID杀死想杀死的应用程序 adb shell kill -9 21997 # 这个程序被杀死了
3.现在使用任务切换回到应用程序。那么现在是一个新的应用实例了。
总结:
保存数据在你的Application对象是容易出错的。并且会让你的程序崩溃。最好的,你应该把你的全局数据保存到磁盘上或者通过Intent的extras明确的传递到Activity
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。