不要在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

 

 

 

 

  

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。