【发布时间】:2014-07-27 18:21:38
【问题描述】:
当在retainInstance 设置为true 的片段中阻止WebView 重新加载时,我遇到了问题。
我尝试过的路线:
SaveInstanceState(由于retainInstance,不会在轮换时传递包) 保存在 onSaveInstanceState 上并在 create 中恢复的自定义包 保留 WebView 引用并尝试将其添加回视图层次结构
一定有更简单的方法吗?
【问题讨论】:
当在retainInstance 设置为true 的片段中阻止WebView 重新加载时,我遇到了问题。
我尝试过的路线:
SaveInstanceState(由于retainInstance,不会在轮换时传递包) 保存在 onSaveInstanceState 上并在 create 中恢复的自定义包 保留 WebView 引用并尝试将其添加回视图层次结构
一定有更简单的方法吗?
【问题讨论】:
你可以很容易地做到这一点。由于您已经保留了实例,因此请在 Fragment 中保留对 WebView 的引用,并在调用 Fragment 的 onDestroyView() 时将其与父级分离。如果它不为空,只需在 onCreateView() 中返回它。例如:
public class RetainedWebviewFragment extends Fragment {
private WebView mWebView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mWebView == null) {
mWebView = new WebView(getActivity());
}
return mWebView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (getRetainInstance() && mWebView.getParent() instanceof ViewGroup) {
((ViewGroup) mWebView.getParent()).removeView(mWebView);
}
}
}
但是,您将在第一次方向更改时泄漏对第一个 Activity 的引用——我还没有想出如何避免这种情况。 t据我所知,无法在视图上设置上下文。不过,如果您对那个内存泄漏没问题,这确实有效。
编辑:或者,如果您像我在此示例中所做的那样以编程方式实例化它,您可以使用getActivity().getApplicationContext() 来避免泄漏活动。如果您使用提供的 LayoutInflater,它会在充气时将应用程序的上下文提供给视图。
不要将应用程序上下文用于 WebView - 这会在显示下拉视图时导致意外崩溃并可能出现其他问题。
【讨论】:
WebView(只会发生一次)时,你给它一个对当前Activity的引用,它保存在里面(你可以用View.getContext()检索它. 当 Activity 被销毁并重新创建时,View 引用仍然保留(其中仍然包含对已销毁Activity 的引用)并且无法使用新的View 引用更新Activity 引用(除了可能使用反射在内部更新字段)。