Fre*_*red 8 android webview android-webview android-configchanges android-view
我的网络应用程序在Chrome中运行良好,可以很好地处理配置更改(例如屏幕旋转).一切都完好无损.
将我的网络应用加载到WebView我的Android应用中时,网络应用会在屏幕方向更改时失去状态.它确实部分保留了状态,即它保留了<input>表单元素的数据,但是所有的JavaScript变量和DOM操作都会丢失.
我希望我的WebView能够像Chrome一样运行,即完全保留状态,包括任何JavaScript变量.需要注意的是,虽然Chrome和WebView源自相同的代码库,但Chrome内部不使用WebView.
屏幕方向更改发生的情况是Activity(以及任何最终的片段)被销毁然后随后重新创建.WebView继承View和覆盖方法onSaveInstanceState以及 onRestoreInstanceState处理配置更改因此它会自动保存和恢复任何HTML表单元素的内容以及后退/前进导航历史状态.但是,不保存和恢复JavaScript变量和DOM的状态.
已经提出了一些解决方案.所有这些都是非工作的,只保留部分状态或其他方式不理想.
WebView继承了View具有方法的方法setId,该方法也可以使用元素android:id声明中的属性在布局XML文件中声明<WebView>.这是保存和恢复状态所必需的,但状态仅部分恢复.这将恢复表单输入元素,但不恢复JavaScript变量和DOM的状态.
并且自API级别13以来onRetainNonConfigurationInstance已弃用.getLastNonConfigurationInstance
通过在文件中或通过方法设置元素的screenOrientation属性,可以强制活动屏幕方向.这是不希望的,因为它打破了屏幕旋转的期望.这也只涉及屏幕方向的变化而不是其他配置变化.<Activity>AndroidManifest.xmlsetRequestedOrientation
不行.setRetainInstance在片段上调用方法确实会保留片段(它不会被破坏),因此片段的所有实例变量都会被保留,但是它会破坏片段的视图,因此WebView它会被破坏.
该configChanges属性可以被声明为Activity中AndroidManifest.xml文件android:configChanges="orientation|screenSize"处理配置更改,防止它们.这有效,它可以防止活动被破坏,因此WebView它的内容被完全保留.然而,这是不鼓励的,并且据说仅作为最后的解决方案使用,因为它可能导致应用程序以微妙的方式打破并且变得越来越多.设置属性onConfigurationChanged时会调用该方法configChanges.
我听说MutableContextWrapper可以使用,但我没有评估这种方法.
WebView有方法saveState和restoreState.请注意,根据文档,该saveState方法不再存储WebView的显示数据,无论这意味着什么.无论哪种方式,这些方法似乎都不能完全保留WebView的状态.
这WebViewFragment只是一个方便的片段,包装WebView给你,所以可以轻松地使用更少的样板代码,就像ListFragment.它没有做任何额外的状态保持完全保持状态.
是否有任何真正的解决方案来解决WebView在配置更改后被破坏和丢失状态的问题?(如屏幕旋转)
一种完全保留所有状态的解决方案,包括JavaScript变量和DOM操作.一个干净且不基于黑客或弃用方法的解决方案.
在研究和尝试不同的方法之后,我发现了我所相信的最佳解决方案.
它采用setRetainInstance沿与保留片段的实例addView,并removeView在onCreateView和onDestroyView防止方法WebView从被破坏掉了.
MainActivity.java
public class MainActivity extends Activity {
private static final String TAG_FRAGMENT = "webView";
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebViewFragment fragment = (WebViewFragment) getFragmentManager().findFragmentByTag(TAG_FRAGMENT);
if (fragment == null) {
fragment = new WebViewFragment();
}
getFragmentManager().beginTransaction().replace(android.R.id.content, fragment, TAG_FRAGMENT).commit();
}
}
Run Code Online (Sandbox Code Playgroud)
WebViewFragment.java
public class WebViewFragment extends Fragment {
private WebView mWebView;
public WebViewFragment() {
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_webview, container, false);
LinearLayout layout = (LinearLayout)v.findViewById(R.id.linearLayout);
if (mWebView == null) {
mWebView = new WebView(getActivity());
setupWebView();
}
layout.removeAllViews();
layout.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return v;
}
@Override
public void onDestroyView() {
if (getRetainInstance() && mWebView.getParent() instanceof ViewGroup) {
((ViewGroup) mWebView.getParent()).removeView(mWebView);
}
super.onDestroyView();
}
private void setupWebView() {
mWebView.loadUrl("https:///www.example.com/");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3171 次 |
| 最近记录: |