13

根据 Android API 文档,Activity.onRetainNonConfigurationInstance()已被弃用,取而代之的是Fragment.setRetainInstance()

但是,我遇到了两种不同的情况,其中 Fragment.setRetainInstance() 似乎不可行。

  1. 如果 Fragment 包含 WebView。根据Diane Hackborne的说法,您不能在配置更改时重复使用 WebView。我猜这意味着您需要允许 Fragment 在屏幕旋转时拆除并重新创建 WebView,并使用WebView.saveState()WebView.restoreState()来恢复 Web 视图状态。

  2. 如果 Fragment 属于配置更改后不再存在的布局,当 FragmentManager 尝试恢复 Fragment 时,会抛出:

    java.lang.IllegalArgumentException: No view found for id 0x7f060091 for fragment
    

    这可能会发生(例如),如果您在横向模式下有两个片段布局,但在纵向模式下有一个片段布局。从横向旋转到纵向时,如果 setRetainInstance() 设置为 true,则两个 Fragment 都不会被破坏,但一个 Fragment 不再具有要重新附加的有效视图,因此会出现异常。

因此,如果您正在构建基于 Fragment 的应用程序,并且您需要在配置更改之间保留数据(例如对运行 AsyncTasks 的引用),并且您不能使用Fragment.setRetainInstance(),并且没有 Fragment.onRetainNonConfigurationInstance (),最好的方法是什么?

4

2 回答 2

8

即使您使用Fragment.setRetainInstance(),Fragment 仍然会在配置更改后拆除其视图并重新创建它。也就是说,onDestroyView()并将onCreateView()按该顺序调用。确保在onDestroyView(). 您不必担心重新使用 WebView - 将使用正确的Activity上下文重新创建新的 WebView。这有点无关紧要,因为要保存 WebView 状态,您仍然需要调用WebView.saveState(Bundle)inFragment.onSaveInstanceState(Bundle)WebView.restoreState(Bundle)in Fragment.onViewCreated(Bundle)。这只是意味着它Fragment.setRetainInstance()仍然与 WebViews 的使用兼容。

您给出的关于不再存在于另一个方向的视图容器的示例意味着您不需要保留任何数据 - 屏幕旋转后根本不会使用该片段。

在任何情况下,您都可以将它们分成两个 Fragment,而不是让一个 Fragment 同时处理 UI 和 AsyncTask 加载——具有 AsyncTask 的一个根本不需要附加到视图层次结构中,并且可以设置为保留的实例。这简化了您的顾虑,并使架构更加简洁。当 AsyncTask 完成时,您需要回调 UI 片段以传递结果(例如 findFragmentById/Tag、setTargetFragment、自定义侦听器...)。管理 AsyncTask 的片段需要能够在旋转后检索对 UI 片段新实例的引用。

于 2012-08-04T02:18:50.310 回答
0

看起来我的问题没有答案,但这是我最终做的:

  1. 对于包含需要恢复的WebView的Fragment ,覆盖Fragment.onSaveInstanceState(Bundle state)并调用WebView.saveState(bundle)。然后在Fragment.onViewCreated(View view, Bundle savedInstanceState)中,如果savedInstanceState不为 null ,则调用webView.restoreState(savedInstanceState) 。

  2. 对于包含需要保留的实时AsyncTasks的片段,覆盖Fragment.onDestroy ()并将这些任务保存在我的应用程序对象中。(或者,也建议将它们存储在静态变量中)。然后在Fragment.onCreate(Bundle savedInstanceState)中,检查这些任务是否不为空,如果是,则恢复它们。(这意味着依赖于应用程序,但在我的情况下,我会在AsyncTask完成时恢复要在Fragment上调用的回调)。

我不确定这是否是最好的解决方案,但它似乎解决了我遇到的问题。

尽管如此,我发现整个情况相当混乱(区分onSaveInstanceState()onRetainNonConfigurationInstance()onDestroy(),并决定在每种情况下需要保存什么)。

于 2012-08-02T05:48:04.337 回答