【问题标题】:Prevent WebView reloads in FragmentPagerAdapter?防止 WebView 在 FragmentPagerAdapter 中重新加载?
【发布时间】:2013-01-27 21:13:45
【问题描述】:

我有一个 FragmentPagerAdapter 用于显示大约 6 个选项卡,所有这些选项卡都从 Web 服务器加载它们的数据。其中一个选项卡包含一个从我的服务器加载图像的 WebView。 生成图像的服务器端成本很高,因此我想减少重新加载 WebView 的调用次数。 对于非 WebView 选项卡,我已经能够保存我的状态(对于那些,只是一个简单的数组)并在标签被刷过时恢复它们。

问题:

  • 每次我使用 FragmentPagerAdapter 滑回 WebView 时都会重新加载,这会导致重新加载时间过长并且我的 Web 服务器上的负载很高。

考虑的解决方案:

  • 使用ViewPager.setOffscreenPageLimit() 这是有问题的,因为它会强制加载更多选项卡,即使它们永远不会被查看。这在我的服务器上是不必要的昂贵。
  • 使用WebView.saveState()WebView.restoreState() 文档已更新,以明确此处不再维护显示状态,因此这对这种情况不再有用。
  • 将我的活动设置为:android:configChanges="keyboardHidden|orientation|screenSize" 这适用于旋转情况,但不会影响 ViewPager/FragmentPagerAdapter 在选项卡情况下滑动。

听起来WebView.saveState() 的旧行为会很完美...

【问题讨论】:

  • 我首先要弄清楚片段中的什么触发了重新加载。 WebView 本身对寻呼机和片段一无所知,因此某个地方的某个人正在对 WebView 执行某些操作以触发重新加载。然后,您可以努力抑制这种行为。
  • 在 onCreateView 中,我有以下内容: wv = (WebView) view.findViewById(R.id.radarWebView); if(savedInstanceState != null) { wv.restoreState(savedInstanceState); } 其他 { wv.loadUrl(myURL); }
  • 据我所知,主要是滑动会导致 Fragment 被破坏。当它回来时,它会尝试恢复状态,但由于 WebView 不再能够恢复显示状态,它必须重新加载(据我所知,这是最好的)。
  • “据我所知,主要是滑动导致 Fragment 被破坏”——不是FragmentPagerAdapterFragmentPagerAdapter 是“PagerAdapter 的实现,它将每个页面表示为一个 Fragment,只要用户可以返回该页面,它就会永久保存在 Fragment 管理器中。” “在 onCreateView 中,我有以下内容”——您是否确定每次滑动时都会调用 onCreateView(),即使对于以前查看过的页面也是如此?
  • 我知道一旦标签超过 setOffscreenPageLimit() 的限制,就会调用 onResume 和 onCreateView。

标签: android android-fragments android-webview


【解决方案1】:

问题似乎是您正在抹杀自己的结果。

虽然您在配置更改时需要新的WebView,但在其他情况下您不需要新的WebView。而且,如果您已经拥有WebView,则无需告诉它执行任何操作。

所以,我会试试这个:

  • 保留您在片段数据成员的onCreateView() 中创建的WebView
  • 如果该数据成员是null,则仅在onCreateView() 中扩展布局
  • 仅当您膨胀布局时才调用 loadUrl()

(如果您在 Java 代码中创建 WebView,请将“膨胀布局”替换为“通过其构造函数创建 WebView”)

如果片段的内容多于WebView,您还需要保留在数据成员中膨胀的根视图,以便从onCreateView() 返回。

【讨论】:

  • 感谢您的回答。鉴于 WebView 只是片段中通过 XML 膨胀的几个视图之一,您会推荐哪种方法?
  • @DerekJohnson:坚持你膨胀的根视图。只有当它是null 时才膨胀。如果您充气,请仅致电loadUrl()
  • 当我将整个视图保存在一个实例变量中时,重新添加后我得到:java.lang.IllegalStateException:指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。我知道我需要分离视图 onStop() 但 getView() 和 getParent() 不提供 removeAllViews() 或 removeView()。
  • @DerekJohnson:将getParent()返回的ViewParent转换为ViewGroup并调用合适的remove方法。
  • 非常感谢这个标记,我在 FragmentTabHost 中的 WebView 遇到了类似的问题,您的建议很有效
猜你喜欢
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2014-04-16
  • 1970-01-01
  • 2015-06-17
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多