Android:内存不足时静态变量为空

发布于 2024-10-14 09:36:11 字数 539 浏览 3 评论 0原文

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

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

当我的应用程序进入后台一段时间或当我的应用程序使用大量内存时,这些静态变量将变为空。

  1. 如何预防?

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

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

  3. 如果这些数据太大而无法在 Intent 中序列化,无法使用数据库(无论出于何种原因),并且无法通过以下方式存储在文件中,那么保持某些数据在活动之间可访问的最佳方法是什么序列化也可以吗?

I have an application which has some static variables.
These variables are stored in an independent Class named DataContext.
These variables are initialized from raw files at the application start (a method named DataContext.initConstant() is called in the onCreate() of MyApplication which extends Application).

(EDIT : the initConstant method use an AsyncTask to load this data from files).

When my application comes to the background for a certain time or when my application used to much memory, these static variables become null.

  1. How can it be prevented?

  2. If not what should I do with my static variables?

    I have other data which are stored in static variables to be used across different activities, but I clear them or pass them to null in the onLowMemory() of MyApplication.

  3. What is the best way to keep some data accessible between activities if these data are too big to be serialized in an Intent, a database can't be used (for whatever reason), and can't be stored in files through serialization either?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

苍风燃霜 2024-10-21 09:36:11
  1. 你不能。 Android 需要不时释放内存。想象一下,如果所有应用程序都有大量应该永久驻留的静态数据 - 您将如何将其放入内存中?这是一部手机。它没有虚拟内存。

  2. (和 3):任何想要持久化的内容都需要通过 SharedPreferences、Sqlite 数据库或文件来存储。

    (和

  1. You can't. Android needs to free up memory from time to time. Imagine if all applications had a ton of static data that is supposed to be resident forever - how would you fit that in memory? It's a mobile phone. It doesn't have virtual memory.

  2. (and 3): Anything that is intended to be persistent needs to be stored, either via SharedPreferences, a Sqlite database, or a file.

海夕 2024-10-21 09:36:11

最有可能的问题是,您的应用程序在后台时被终止,然后在您返回时重新创建。请查看 Activity Lifecycle 文档,了解何时可能发生这种情况单一活动。您需要确保在正确的时间点将存储在内存中的任何内容移动到更永久的存储中,以避免在应用程序被终止时丢失该信息。

我不确定您到底要存储什么,但听起来使用共享首选项可能效果很好。 数据存储上的此页面解释了多种不同的方法永久存储数据,包括共享首选项。

Most likely the issue is that your application is being killed while it is in the background, and then recreated when you come back to it. Check out the Activity Lifecycle documentation on when this might occur for a single activity. You need to make sure that you move anything stored in memory to more permanent storage at the correct point in time to avoid losing that information if the app gets killed.

I'm not sure what exactly you are storing, but it sounds like using Shared Preferences might work well. This page on Data Storage explains a number of different ways of more permanently storing data, including Shared Preferences.

毁梦 2024-10-21 09:36:11

如果您没有使用原始文件,我建议在加载类时进行初始化。

例如,

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

如果您以这种方式加载文件,您确实需要担心一些更大的问题。例如,I/O 错误或延迟问题怎么办?在主线程中执行 I/O 时,您将在姜饼中收到警告(如果启用它们)。也许您应该有一个对象来检索这些值,而不是具有静态字段的类。 (也许使用静态缓存,尽管您应该在检查/更改它之前对其进行同步)

If you weren't using raw files, I'd advise initializing when the class is loaded.

For instance,

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

You do have some bigger concerns to worry about if you are loading files that way. For instance, what about I/O errors, or latency issues? You will get warnings in gingerbread (if you enable them) for doing I/O in your main thread. Perhaps you should have an object to retrieve these values instead of a class with static fields. (perhaps with a static cache, although you should synchronize on it before checking/changing it)

泅人 2024-10-21 09:36:11

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

In your onResume() method you could query the static data to see if it is present and if not, load it back in again.

缺⑴份安定 2024-10-21 09:36:11

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

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

正确的方法是使用 sharedPreference保留缓存数据。

您可以创建自己的所需数据的 getter 和 setter,并将其包装在 sharedPreference 对象周围。当您使用 getter 访问时,您应该始终检查该值是否为空或过期。使用 setter 时,您可以存储 update_time

对于特定于活动的数据,您可以仅使用 getPreference(permission),如果您想在活动和其他应用程序组件之间共享数据,则可以使用 getSharedPreference(name,permission)

通常,权限将为 MODE_PRIVATE,这样数据只能在您的应用程序内访问。

您应该对数据进行分组并存储在不同的sharedPreference 对象中。这是一个很好的做法,因为当您想要使该组数据无效时,只需一个行即可。

editor.clear(); editor.commit()

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

I assume this is a data cache problem.

Storing data in static class is not guaranteed to work when user swap apps often. Android system will reclaim any background activity when memory is low. Static class is definitely among this category.

The proper way to do it is to use sharedPreference to persist cache data.

You can create your own getter and setter of the data you want and wrap it around sharedPreference object. When you access using getter, you should always check if the value is empty or expired. You can store an update_time when using setter.

For activity specific data, you can just use getPreference(permission), if you want to share data across activities and other applications components, you can use getSharedPreference(name, permission).

Normally, the permission will be MODE_PRIVATE such that the data can only be accessed within your application.

You should group data and store in difference sharedPreference object. This is good practice because when you want to invalidate that group of data, it is just a matter of one liner.

editor.clear(); editor.commit()

If you want to cache complex object, you should serialize it. I prefer JSON format. So you need some conversion mechanism in place. To do this, I will create my data object class extending JSONable class. JSONable class will have toJSON() method and readFromJSON(). This is convenient when restore and serialize data.

渔村楼浪 2024-10-21 09:36:11

我在静态作用域中存储一个 User 对象和一个 Client 对象。我注意到引用有时会变成空。所以现在在我的吸气剂中,我检查该值是否为空,如果是,我重新启动应用程序。

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

我也可以选择重新加载客户端,因为我将访问令牌存储在首选项中,但是我做了太多初始化,因此我决定重新启动应用程序是最好的主意。

I store a User object and a Client object in my static scope. I have noticed from time to time the reference becomes null. So now in my getters I check to see if this value is null and if so I restart the app.

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

I could have also chosen to reload the Client because I store the Access Token in prefs however I do so much initialization that I decided restarting the app would the best idea.

吾性傲以野 2024-10-21 09:36:11

您可以使用共享首选项来存储值,而不是使用静态变量。

注意:对于共享偏好,您也不应该给予过重的负载。

我通过使用带有 getter 和 setter 函数的超类来存储和检索共享首选项变量,解决了这个问题。

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

Instead of using the static variable u can use the shared preference for storing the value.

Note: for shared preference also you should not give heavy load.

I have solved this problem by having the super class with getter and setter function for storing and retrieving shared preference variable.

All class in my application extended the super class instead of activity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文