首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在内存不足的情况下保存实例状态

在内存不足的情况下保存实例状态
EN

Stack Overflow用户
提问于 2015-05-04 16:58:04
回答 1查看 1.5K关注 0票数 3

我有一个由DialogFragment类环绕的警报对话框。该对话框具有自定义布局,其中显示了项目列表(我使用带有适当适配器的ListView )。项目列表非常庞大和重要,所以我将其保存在DialogFragment's onPause()中的一个onPause()类中,就像在这个例子中一样。

除了一种非常罕见的情况:当我打开对话框(按下"home“按钮)而设备内存不足时,它会扼杀应用程序的进程,这一切都很完美。当我稍后回到我的应用程序时,它会尝试重新创建对话框,但是会崩溃(我在对话框的ListView适配器中获得了一个ListView),因为它无法恢复左打开对话框中显示的项目列表。这是因为当系统停止应用程序的进程时,我存储对话框状态的Fragment也会被破坏,所以我的DialogFragment无法重新创建它的对话框,因为它没有列表适配器的数据源。

我想要的是提供一种更好的方法来保存我的对话框窗口的状态,这样即使在我的应用程序进程结束后也可以重新创建它,或者向我展示一种取消对话框的方法,如果项目列表在恢复之前是null的话(我的意思是在对话框恢复之前取消它)。我不认为数据库是存储数据的好方法,因为这需要太长时间。如果没有关于适配器的信息,我更愿意使用一种方式来停止对话框的娱乐。

更新:

在应用程序的生命周期中实现Parcelable来保存对象确实是一个很棒的想法。向Parcel编写对象是快速的(相信我,在您开始不适当地使用它之前,您不会看到生命周期变化之间的任何延迟),而保存和恢复应用程序实例状态的过程由ActivityManager进程控制,因此即使不仅仅是您的Activity,而且承载您整个应用程序的进程都被安卓系统破坏了,ActivityManager仍然维护保存对象的Parcel,如果在一个新的进程中从零开始重新创建ActivityActivityManager就会重新存储对象的状态。非常感谢纳维德鼓励我尝试这种做法!

请注意,对于那些仍然不知道保存实例状态到底是什么的人来说:

Activity的实例状态保存在其生命周期事件中意味着维护仅对应用程序当前UI或用户当前进度有意义的信息更改,但当应用程序或用户显式停止应用程序(按后退按钮)并在稍后再次启动时,这些更改并不是必需的。这种真正是临时的特殊形式的信息应该保存在Bundle对象中的Bundle回调方法中,方法是使用用于原始Java类型的put...()方法或在自定义类中实现Parcelable接口,然后在onCreate()onRestoreInstanceState() callbakcs中恢复。

对于用户非常重要的所有其他数据,无论是显式关闭应用程序还是只保留很短的时间,都应该保存在持久存储中,例如SQLite数据库或SharedPreferences系统,以便每当用户或应用程序再次需要其先前的进度时,就可以还原这些数据。您应该在onPause()回调方法中保存这种形式的数据,因为这是在系统能够破坏应用程序的进程之前保证调用的最后一个方法,以防它需要恢复某些资源。如果您选择在onPause()之后调用的方法(即onStop()onDestroy() )中保存数据,您将面临无法保存数据的巨大风险,因为如果系统决定在某些非常糟糕(但不一定很少见)的情况下立即关闭应用程序,则这些方法可能永远不会被调用。

另一件事:请只在存储少量数据时使用SharedPreferences,因为它不是为存储列表、集合或包而构建的。考虑多花几个小时为您的应用程序实现一个SQLite数据库接口,并使用它来维护大量信息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-04 17:22:31

由于内存问题,当系统即将关闭应用程序时,系统会调用onSaveInstanceState。您可以在onSaveInstanceState中保存任何与状态相关的信息。如果您的数据是一个原始类型、Parcelable或Serializable,则可以将其保存在一个包中。

在重新创建该活动时,您可以在onRestoreInstanceStateonCreate中或在碎片生命周期中的任何一个中还原它。

代码语言:javascript
复制
onCreate(Bundle) called to do initial creation of the fragment.

onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view  hierarchy associated with the fragment. 

onActivityCreated(Bundle) tells the fragment that its activity has    completed its own Activity.onCreate(). 

onViewStateRestored(Bundle)tells the fragment that all of the saved state of its view hierarchy has been restored.

如果你只是不想显示对话框。然后,您可以在onResume中执行空检查,如果数据为空,则不要创建适配器,如果可以看到,则关闭该对话框。

更新:示例parcelable:

代码语言:javascript
复制
public class MyObject implements Parcelable {

        private String myString;
        private int myInt;

    protected MyObject(Parcel in) {
        myString = in.readString();
        myInt = in.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(myString);
        dest.writeInt(myInt);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
        @Override
        public MyObject createFromParcel(Parcel in) {
            return new MyObject(in);
        }

        @Override
        public MyObject[] newArray(int size) {
            return new MyObject[size];
        }
    };
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30035634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档