【问题标题】:Save object while orientation change方向更改时保存对象
【发布时间】:2011-12-02 05:18:03
【问题描述】:

如何在方向改变时保存对象,因为 onRetainNonConfigurationInstancegetLastNonConfigurationInstance 已被弃用。我不能与compatibility package android-support-v4.jar FragmentActivity 一起使用,它显示Cannot override the final method from FragmentActivity

开发者网站说

改用新的 Fragment API setRetainInstance(boolean);

但我不知道如何使用setRetainInstance 保存自定义对象

我的场景:
在我的活动中,我有一个带有进度对话框的 AsyncTask。在这里我需要处理方向变化。
为此,我从 CommonsWare 的 Mark Murphy 那里得到了很好的回答
background-task-progress-dialog-orientation-change-is-there-any-100-working,
sample project

由于我使用的是兼容包 android-support-v4.jar,FragmentActivity,我无法覆盖 onRetainNonConfigurationInstance
无法覆盖 FragmentActivity 中的 final 方法

有没有其他方法可以保存我的自定义对象?

编辑: 我不能使我的 AsyncTask 任务 Parcelable (如果我没记错的话),因为它使用接口、上下文等。 我的AsyncTask

 public class CommonAsyncTask extends AsyncTask<Object, Object, Object>  {
        Context context;
        AsyncTaskServices callerObject;
        ProgressDialog progressDialog;
        String dialogMessag ; 
    ................

我正在寻找,是否有任何 onRetainNonConfigurationInstance 方法的替代方法,它可以在方向更改时完全保存对象,以后可以使用getLastNonConfigurationInstance 检索

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    有两种选择:

    1. 使用LoaderFragmentActivity 将负责在重新创建时保存/恢复其状态。
    2. 使用没有视图的片段并在其上调用setRetainInstance(true)。在兼容性库的源代码 FragmentRetainInstanceSupport 或类似的代码中有一个示例。

    【讨论】:

    • 感谢 Nikolay Elenkov 将我引导至 loader,经过一番激战后,我在 fragment 中使用 loader 完成了此操作
    • 你能告诉我你是如何处理进度对话框的显示/关闭的吗?因为这些片段事务在 onLoadFinished 中是被禁止的?
    • 使用FragmentTransaction.commitAllowingStateLoss()。听起来很脏,但似乎没有其他办法。或者,更好的是,不要使用进度对话框。使用操作栏微调器(不确定进度)或其他东西。对话框通常不值得麻烦。
    • 有趣。这是最近添加的吗?我不记得以前见过它。
    • @NikolayElenkov 如果您的片段确实有视图,这不合适吗?
    【解决方案2】:

    您可以使用onRetainCustomNonConfigurationInstance.

    使用它代替 onRetainNonConfigurationInstance()。稍后检索 使用 getLastCustomNonConfigurationInstance()。

    【讨论】:

    • 这与提问者明确试图避免的onRetainNonConfigurationInstance() 相同(在问题的第一句话中同样如此!)
    • 不,不一样。请参阅文档:developer.android.com/reference/android/support/v4/app/… OP 并没有说他试图避免使用 onRetain...(),他只是说它没有编译,因为它已在支持库中被声明为 final(这都是真的)。我认为这个解决方案在迁移到新的做事方式时作为保留/解决方法是有效的。
    • 有时我觉得这些 API 变得比它们应该的更复杂。
    【解决方案3】:

    好吧,引用Android Developers' References

    该方法在活动开始时在onStart()之后调用 从先前保存的状态重新初始化,在此处给出 保存的实例状态。大多数实现将简单地使用 onCreate(Bundle) 来恢复它们的状态,但有时是 完成所有初始化后,方便在这里进行 或允许子类决定是否使用您的默认值 执行。此方法的默认实现执行 恢复以前被冻结的任何视图状态 onSaveInstanceState(Bundle)。

    关于onSaveInstanceState() 的使用,最好使用onRestoreInstanceState() 来还原您的对象/事物。

    Refer to Activity#onRestoreInstanceState()

    【讨论】:

    • 查看我的编辑,我无法使我的 AsyncTask 任务 Parcelable(如果我没记错的话),因为它使用接口、上下文等...与onSaveInstanceState一起使用
    • onRestoreInstanceState() 不是onSaveInstanceState() 的替代品——事实上,没有它它完全没用。引用只是提到在某些情况下使用onRestoreInstanceState() 比使用onCreate() 更方便。
    【解决方案4】:

    当你的 Fragment 暂停时,它会调用这个方法:

    @Override
    public void onSaveInstanceState(Bundle outState) {
        // Add variable to outState here
        super.onSaveInstanceState(outState);
    }
    

    当 Fragment 重新启动时,变量 outState 将被输入到 onCreate() 方法中。

    您可以保存任何基本类型或实现Parcelable接口的数据

    【讨论】:

    • 查看我的编辑,我不能让我的 AsyncTask 任务 Parcelable(如果我没记错的话),因为它使用界面、上下文等。
    • 嗯...请留下评论 /why/ 你对答案投反对票,否则我们不知道为什么它实际上不正确?
    • 我同意投反对票并发表评论会有所帮助。但在这里我不知道是什么/谁给了你(我看不到任何反对票
    • +1 指出捆绑包将在 onCreate 方法中可用,而不是像我尝试的那样在 onCreateView 或 onViewCreated 中可用。
    • 替换片段时也会调用这个吗?
    猜你喜欢
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多