【问题标题】:Objects just disapper after a few hours (Android)对象在几个小时后消失(Android)
【发布时间】:2014-01-22 21:42:38
【问题描述】:

我有一个自定义对象列表...这些对象简单地监视我的一些网站以查找用户可能添加的任何新数据。我将这些对象保存在一个静态 List 中,它是 final 类的成员……我创建了一个服务,以给定的时间间隔遍历列表并根据需要进行更新。

final public class MonitorHandler {
    public static List<MonitorSettings> monitorsSettings = new ArrayList<MonitorSettings>();

    ect....

}

在一段时间内一切都运行良好......根本没有例外。但是,如果我让应用程序运行一段时间......就像说一夜之间列表是空的......就像这些对象已被 android 垃圾收集或删除。为什么是这样??即使在应用程序关闭或发送到后台后,静态对象是否仍然存在?

【问题讨论】:

    标签: android class object static


    【解决方案1】:

    这是为什么?

    您的进程已终止。

    即使在应用程序关闭或发送到后台后,静态对象是否仍然存在?

    仅在进程运行时。一旦不再处于前台,您的进程就可以终止。这需要几秒钟还是几小时取决于设备的情况。

    如果您有想要闲逛的数据,请使用数据库、文件或SharedPreferences 以持久方式存储它。

    【讨论】:

    • 我可以在 SharedPreferences 中添加一个 List 吗??
    • @SteveJpbs:您可以在 API 级别 11+ 的 SharedPreferences 中添加 Set&lt;String&gt;
    • 嗯,这行不通...... MonitorSettings 对象有些复杂。
    【解决方案2】:

    这是为什么?即使应用程序关闭或发送到后台,静态对象是否仍然存在?

    不,如果您的应用实际上已被系统关闭,则可能会发生这种情况。您应该登录您的 Service.onDestroy() 以确保这确实是原因,但不能保证实际会调用 onDestroy。

    因此,您应该将数据保存在一些存储中,最好是 SharedPreferences 或 DB - sqlite。

    【讨论】:

      【解决方案3】:

      您没有显示足够的代码来确定,但很可能您在应用程序中的任何地方都没有对您的数据进行引用,除了 MonitorHandler 类的静态元素。 Dalvik VM会不时卸载未引用的类,因此下次访问该类时会重新加载它,重新运行静态初始化,最终得到一个新的空列表。

      最重要的是,在执行 Android 应用程序期间,您可以依赖的不被卸载的 唯一 类是 Application 类本身。

      如果您想在您的应用程序中保留数据,唯一可行的方法是从您的应用程序类中维护对它的引用。对于您的列表,最简单的方法是将其直接放入您的 Application 类中。对于更复杂的数据,您可能希望创建一个单独类的实例并在您的 Application 类中静态保存对它的引用。这是一个示例,展示了两种不同的数据创建方式,一种是静态的,一种是惰性的。

      import android.app.Application;
      import android.content.Context;
      import com.example.DiskLruImageCache;
      
      import java.util.ArrayList;
      import java.util.List;
      
      public class TestApp extends Application {
      
          static final public int CACHE_SIZE = 1024 * 1024 * 15;        // 15MB
          private static List<String> stringList = new ArrayList<String>();
          private static DiskLruImageCache imageCache = null;
          private static Context context;
      
          @Override
          public void onCreate() {
              super.onCreate();
              context = this;
          }
      
          public static List<String> getStringList() {
              return stringList;
          }
      
          static public DiskLruImageCache getImageCache() {
              if(imageCache == null) {
                  synchronized(context) {
                      if(imageCache == null)
                          imageCache = new DiskLruImageCache(context, "TestImages", CACHE_SIZE);
                  }
              }
              return imageCache;
          }
      
      }
      

      现在在您的活动或服务中,您只需致电TestApp.getStringList() 即可获取列表。只要应用程序正在运行,对此所做的任何更改都会被保留。

      【讨论】:

      • 把静态列表放在服务本身怎么样..这是好的还是不好的做法?
      • “Dalvik VM 将不时卸载未引用的类”——不是根据可能编写该部分 VM 的人所说:stackoverflow.com/questions/18840093/…
      • @SteveJpbs 不,将其放入服务中是行不通的——服务也不能保证保留在内存中。我在自己的应用程序中经历了所有这些迭代,并且使用 Application 类是唯一有效的方法。
      • @CommonsWare 好吧,它可能不会卸载类,但如果没有实时引用,它肯定会重新加载它们类,具有相同的效果。在追踪类似于 OP 描述的错误时,我已经最终证明了这一点。我不知道是否有任何方法可以检测何时卸载类,但我能够在类中的静态块中记录代码的重新执行,并且这只应在加载类时发生。跨度>
      • @Clyde:很可能,该类已重新加载,因为进程已终止,并且该类已加载到新进程中。
      猜你喜欢
      • 2023-03-15
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 2019-11-02
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多