2

DialogFragment我有一个由类包裹的警报对话框。该对话框具有自定义布局,我在其中显示项目列表(我将 aListView与适当的适配器一起使用)。项目列表非常庞大且重要,因此我将其保存Fragment在我的类中DialogFragmentonPause()就像在此示例中一样。

一切正常,除了一种非常罕见的情况:当我在对话框窗口打开的情况下(通过按“主页”按钮)离开应用程序并且设备内存不足时,它会终止我的应用程序的进程。当我稍后回到我的应用程序时,它会尝试重新创建对话框,但会崩溃(我NullPointerException在对话框的ListView适配器中得到一个),因为它无法恢复在我的左打开对话框中显示的项目列表。发生这种情况是因为Fragment当系统终止我的应用程序的进程时,我存储对话框状态的位置也会被破坏,因此我DialogFragment无法重新创建它的对话框,因为它的列表适配器没有数据源。

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

更新:

在应用程序的生命周期中实现Parcelable保存对象确实是一个绝妙的主意。写入对象Parcel很快(相信我,在您开始不恰当地使用它之前,您不会看到生命周期更改之间有任何延迟),并且保存和恢复应用程序实例状态的过程由ActivityManager进程控制,因此即使不仅是您的Activity,而且托管整个应用程序的进程也会被 Android 系统破坏,ActivityManager维护对象的保存位置,如果在新进程中从头开始重新创建,Parcel则恢复它们的状态。Activity非常感谢@Naveed 鼓励我尝试这种做法!

对于那些仍然不了解保存实例状态的真正含义的人的注意事项:

保存您Activity的生命周期事件的实例状态意味着维护仅对您的应用程序的当前 UI 或用户的当前进度有意义的信息更改,但当您的应用程序或用户明确停止应用程序时(通过按下后退按钮) 并稍后重新启动。这种真正临时的特殊形式的信息应该保存在对象的onSaveInstanceState()回调方法中,方法是使用原始 Java 类型的方法或在自定义类中实现接口,然后在或callbakcs 中恢复。Bundleput...()ParcelableonCreate()onRestoreInstanceState()

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

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

4

1 回答 1

4

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

重新创建 Activity 后,您可以在片段生命周期onRestoreInstanceState中或onCreate以下任何一项中恢复它。

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.

如果您只是不想显示对话框。然后,您可以进行 null 签入onResume,如果数据为 null,则不创建适配器,如果对话框可见,则关闭该对话框。

更新:示例parcelable:

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];
        }
    };
}
于 2015-05-04T17:22:31.020 回答