【问题标题】:How to prevent static variable became null after application holds for long time如何防止应用程序长时间持有后静态变量变为空
【发布时间】:2014-07-31 15:31:36
【问题描述】:

我很久以前就在市场上开发并发布了一个应用程序。现在一些用户在长时间持有应用程序时指出崩溃。现在我确定了崩溃的原因,即我正在使用一个具有静态变量和方法的类来存储数据(getter 和 setter)。现在我想用任何其他方式替换静态方式。从我的研究中我得到以下建议:

  1. 共享首选项:我必须存储 40 多个变量(字符串、int 和 json 数组和对象),所以我认为使用共享首选项不是一个好主意。

  2. SQLite:有 40 多个字段,我不需要一次保留多个值。我正在从不同的活动中获取字段的值。我的意思是一个活动的名字,另一个活动的年龄等等所以我认为使用 SQLite 也不是一个好主意。

  3. 应用程序类:现在我正在考虑使用应用程序类来存储这些数据。长时间持有应用会丢失静态变量等数据吗?

    • 现在我用应用程序类替换静态变量。请告诉我,应用程序数据在很长一段时间后也变为空?

它可能对某人有用。

即使我的问题没有得到解决方案,我也知道为什么我们不应该使用应用程序对象来保存数据。请查看以下链接

Don't use application object to store data

【问题讨论】:

  • So I think using shared preferences is not a good idea. 为什么??
  • 这么多反对票,请给我一个答案。如果您认为这是不符合标准的问题,那么我准备好在我得到解决方案后删除。
  • SharedPreferences 是最适合您的解决方案。我不知道你为什么认为它是not a good idea..!!
  • +1 我在另一个开发人员启动并正在维护的应用程序中遇到类似问题。
  • @Aniruddha..我必须存储 40 多个字段,并且一些值是 jsonArray 和 JsonObjects...是否可以将这些值存储在 SharedPreference 中?

标签: sqlite static android


【解决方案1】:

通常,如果您必须保留某些东西以防您的 Activity 被破坏,您可以将所有这些东西保存在 onSaveInstanceState 并在 onCreateonRestoreInstanceState 中恢复它们

public class MyActivity extends Activity {

int myVariable;
final String ARG_MY_VAR="myvar";

public void onCreate(Bundle savedState) {
if(savedState != null {
   myVariable = savedState.getInt(ARG_MY_VAR);
} else {
   myVariable = someDefaultValue;
}

public void onSaveInstanceState(Bundle outState) {
    outState.putInt(ARG_MY_VAR, myVariable);
    super.onSaveInstanceState(outState);

}
}

如果 Android 操作系统破坏了您的 Activity,onSaveInstanceState 将被调用并保存您的重要变量。然后当用户再次返回您的应用程序时,Android OS 会恢复活动,您的变量将被正确初始化

但是,当您自己调用 finish() 时不会发生这种情况,只有当 Android 出于某些原因销毁您的 Activity 时才会发生这种情况(这很可能在您的应用处于后台时随时发生)。

【讨论】:

  • 请给我一个详细的描述..谢谢你的回答。
  • 我遇到了类似的问题,以前的开发人员有静态数组列表位图和其他 pojo 类。当应用程序来自后台时,因为变量不再存在应用程序崩溃。有没有快速解决这个问题的方法?
  • @Illegal Argument 对于普通类,您可以使用单例模型 static MyClass getInstance() { if(instance == null) { instance = new MyClass(); } 返回实例; }。这样它总是根据需要被启动。您可能需要添加一些同步,因为它们在书中显示
  • @Alex ...非常感谢,我有时必须存储 jsonArrays 和对象。我们不能将这些值存储在 bundle 中。对吗?
  • 当然 Bundle 没有像 putJsonArray 这样的 API。但是,您可以使用 Bundle 拥有的那些 API 来放置您需要的任何内容。您还可以使您的类可序列化并使用 Bundle.putSerializable 尽管这很容易导致问题。毕竟,也许您仍然可以将 json 保存在 sharedpreference 中
【解决方案2】:

首先,您应该覆盖活动中的 onSaveInstanceState 和 onRestoreInstanceState 方法:

@Override
protected void onSaveInstanceState (Bundle outState){
    outState.putString("myVariable", myVariable);
    // Store all you data inside the bundle
}

@Override
protected void onRestoreInstanceState (Bundle savedInstanceState){
    if(savedInstanceState != null){
        myVariable = savedInstanceState.getString("myVariable");
        // Restore all the variables
    }
}

【讨论】:

    【解决方案3】:

    可以尝试在应用程序空间中使用静态变量吗?

    public class YourApplication extends Application
     {
       private static ApplicationBubblick singleton;
       public  String str;
    
       public static YourApplication getInstance()
        {
          return singleton;
        }
     }
    

    并通过以下方式使用变量:

    YourApplication.getInstance().str = ...; // set variable
    
    ... = YourApplication.getInstance().str; // get variable
    

    在您的应用启动和停止应用的所有服务或活动之前,此变量将一直有效。这在您的应用崩溃时不起作用。

    【讨论】:

    • 我们应该在应用程序类中使用静态变量吗?
    • 不要在应用程序对象中保存数据。developerphil.com/dont-store-data-in-the-application-object
    • 是的,我知道。应用程序对象中的变量生存到应用程序死亡(多次睡眠后被操作系统杀死,崩溃等)。这适用于“快速”案例。正确的方式 - SharedPreferences,但这不是永久保存 biges 数据的最佳解决方案。您还可以通过运行 Sticky Service 或创建每分钟的 BroadcastReceiver 或类似的东西来保护您的应用免于操作系统被杀......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多