Android – 防止WebView重新加载旋转

当我旋转我的屏幕时,WebView重新加载整个页面。 我不能有这个,因为我的一些内容包含dynamic/随机材料。 当前旋转时,屏幕将从loadUrl()方法重新加载原始URL。

任何想法我的代码有什么问题?

MainActivity.java

package com.mark.myapp; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.webkit.WebView; import android.webkit.WebViewClient; public class MainActivity extends Activity { WebView web; String webURL = "http://www.google.co.uk/"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) ((WebView)findViewById(R.id.web)).restoreState(savedInstanceState); web = (WebView) findViewById(R.id.web); web.getSettings().setJavaScriptEnabled(true); web.loadUrl(webURL); web.setPadding(0, 0, 0, 0); web.getSettings().setLoadWithOverviewMode(true); web.getSettings().setUseWideViewPort(true); web.getSettings().setSupportZoom(true); web.getSettings().setBuiltInZoomControls(true); web.setWebViewClient(new HelloWebViewClient()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } private class HelloWebViewClient extends WebViewClient { public boolean shouldOverrideUrlLoading(WebView web, String url) { web.loadUrl(url); return true; } } public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) { web.goBack(); return true; } return super.onKeyDown(keyCode, event); } } 

AndroidManifest.xml中

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mark.myapp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:configChanges="orientation|keyboardHidden"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"/> </manifest> 

我认为主要的问题是你打电话给web.loadUrl(webURL); 另外当savedInstanceState!= null

编辑

尝试:

 if (savedInstanceState == null) { web.loadUrl(webURL); } 

编辑2 :您还需要onSaveInstanceState和onRestoreInstanceState覆盖。

 @Override protected void onSaveInstanceState(Bundle outState ) { super.onSaveInstanceState(outState); web.saveState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); web.restoreState(savedInstanceState); } 

不需要Java编码。 在清单文件中使用这个。

  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 

喜欢:

 <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.Example.WebviewSample.webviewsample" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> 

在标签(清单)

 android:configChanges="orientation|screenSize" 

在class上

 @Override public void onConfigurationChanged(Configuration newConfig){ super.onConfigurationChanged(newConfig); } 

在清单中添加android:configChanges="orientation|screenSize"适用于我

 <activity android:name="com.example.HelloWorld.WebActivity" android:label="@string/title_activity_web" android:configChanges="orientation|screenSize" > </activity> 

在Manifest中添加此代码

 <activity ... android:configChanges="orientation|screenSize"> 

我不相信这会工作了。 在我的情况下,使用WebView.restore(Bundle savedInstanceState)还原状态仍会触发URL的重新加载。

查看restoreState()的文档 ,你会看到它说:

如果在WebView有机会构build状态(加载页面,创build后退/转发列表等)之后调用它,则可能会产生不良的副作用。

请注意,此方法不再恢复此WebView的显示数据。

道具@ e4c5指向我在他的答案正确的方向

当然,极端的行动方式是防止触发活动破坏/创造的方向改变。 如何做到这一点的文件在这里

覆盖onConfigChange方法以避免重新加载方向更改上的数据

AndroidMainfest文件中的活动。

 android:configChanges="orientation|keyboardHidden" 

并在您的WebView设置中也有这些

 webview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null); webview.loadUrl("Your URL To Load"); 

在清单文件中试试这个:

 android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 

将其放置在Manifest.xml文件中:

 android:configChanges="orientation|screenSize" 

这里是一个例子:

 <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar" android:configChanges="orientation|screenSize"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> 

正如这里所引用的,

注意:从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,“屏幕大小”也会改变。 因此,如果要在API级别13或更高级别(由minSdkVersion和targetSdkVersion属性声明)开发时防止因方向更改而导致运行时重新启动,则除了“方向”值之外,还必须包含“screenSize”值。 也就是说,你必须decalare android:configChanges =“orientation | screenSize”。 但是,如果您的应用程序的目标级别为12或更低,那么您的活动始终会自行处理此configuration更改(即使在Android 3.2或更高版本的设备上运行,此configuration更改也不会重新启动您的活动)。

在您的活动中设置android:configChanges="orientation|screenSize"将解决此问题。

另外,请注意以下几点

请记住:当您声明您的活动来处理configuration更改时,您有责任重新设置您提供替代scheme的任何元素。 如果您声明您的活动处理方向更改,并且图像应在横向和纵向之间更改,则必须在onConfigurationChanged()期间将每个资源重新分配给每个元素。