Android:低内存的静态variables为null

我有一个应用程序,它有一些静态variables。 这些variables存储在一个名为DataContext的独立类中。 这些variables是在应用程序启动时从原始文件初始化的(在扩展应用程序的MyApplication的onCreate()中调用一个名为DataContext.initConstant()的方法)。

(编辑:initConstant方法使用AsyncTask从文件加载这些数据)。

当我的应用程序进入某个特定时间的背景或者当我的应用程序用于大量内存时,这些静态variables将变为null。

  1. 如何防止?

  2. 如果不是,我应该如何处理我的静态variables?

    我有其他的数据存储在静态variables中用于不同的活动,但我清除它们或将它们传递给MyApplication的onLowMemory()的null。

  3. 如果这些数据太大而无法在Intent中串行化,数据库无法使用(无论什么原因),并且不能通过序列化存储在文件中,那么在活动之间保留一些数据的最佳方法是什么?

Solutions Collecting From Web of "Android:低内存的静态variables为null"

最有可能的问题是你的应用程序在后台被杀害,然后在你回来的时候重新创build。 查看活动生命周期文档,了解单个活动可能发生的情况。 您需要确保将存储在内存中的内容移动到正确的时间点,以避免在应用程序死亡时丢失该信息。

我不确定你正在存储什么,但听起来像使用共享首选项可能工作。 数据存储上的这个页面解释了更多的永久存储数据的不同方式,包括共享首选项。

  1. 你不能。 Android需要不时地释放内存。 想象一下,如果所有的应用程序都有大量永久居住的静态数据,那么你将如何适应内存? 这是一部手机。 它没有虚拟内存。

  2. (和3):任何旨在持久化的东西都需要通过SharedPreferences,Sqlite数据库或文件进行存储。

如果你不使用原始文件,我build议初始化类加载。

例如,

 public static Map<?,?> myStaticMap = new HashMap<?,?>(); static { //fill myStaticMap } 

如果您正在以这种方式加载文件,则需要担心一些更大的问题。 例如,I / O错误或延迟问题呢? 你会得到姜饼(如果你启用它们)在你的主线程中做I / O的警告。 也许你应该有一个对象来检索这些值而不是静态字段的类。 (也许有一个静态caching,虽然你应该在检查/改变它之前同步它)

我认为这是一个数据caching问题。

当用户经常交换应用程序时,不能保证在静态类中存储数据。 内存不足时,Android系统将回收任何后台活动。 静态类绝对属于这一类。

正确的做法是使用sharedPreference来保存caching数据。

你可以创build你自己想要的数据的getter和setter,并将其包装在sharedPreference对象的周围。 当你使用getter访问的时候,你应该经常检查这个值是否为空或者过期。 您可以在使用setter时存储update_time

对于特定于活动的数据,只要使用getPreference(permission) ,如果要跨活动和其他应用程序组件共享数据,则可以使用getSharedPreference(name, permission)

通常,权限将是MODE_PRIVATE,以便只能在您的应用程序中访问数据。

您应该将数据分组并存储在不同的sharedPreference对象中。 这是很好的做法,因为当你想使这组数据无效时,这只是一个class轮的问题。

editor.clear(); editor.commit()

如果你想caching复杂的对象,你应该序列化它。 我更喜欢JSON格式。 所以你需要一些转换机制。 为此,我将创build扩展JSONable类的数据对象类。 JSONable类将具有toJSON()方法和readFromJSON() 。 恢复和序列化数据时这很方便。

我在我的静态作用域中存储一个User对象和一个Client对象。 我不时注意到引用变为空。 所以现在在我的getters我检查,看看这个值是否为空,如果是的话,我重新启动应用程序。

 Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(i); 

我本来可以select重新加载客户端,因为我将Access Token存储在prefs中,但是我做了很多初始化,我决定重新启动应用程序将是最好的主意。

在你的onResume()方法中,你可以查询静态数据,看看它是否存在,如果不存在,再次加载它。

而不是使用静态variables你可以使用共享偏好来存储值。

注意:对于共享首选项,也不应该给重负载。

我已经通过具有getter和setter函数的超类来存储和检索共享偏好variables来解决这个问题。

我的应用程序中的所有类扩展了超类而不是活动。