102

当我旋转屏幕时,WebView 会重新加载整个页面。我不能拥有这个,因为我的一些内容包含动态/随机材料。当前,当屏幕旋转时,会从 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>
4

12 回答 12

116

我认为主要问题是您调用 web.loadUrl(webURL); 当 savedInstanceState != null

编辑

尝试:

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

EDIT2:您还需要 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);
}

注意:还请在您的 Activity 中添加您的 AndroidManifest.xml android:configChanges="orientation|screenSize" 谢谢

于 2012-08-26T14:50:18.487 回答
67

编辑: 找到更合适的解决方案。

新的:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.Example.WebviewSample">
    <application
        <activity android:name=".WebViewActivity"
            <!-- ADD THIS -->
            android:configChanges="orientation|screenSize">
        </activity>
    </application>
</manifest>

WebViewActivity.java文件中将此添加到onCreate()方法

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    wView = (WebView) findViewById(R.id.webView);
    if (savedInstanceState == null) {
        wView.loadUrl("https://google.com");
    }
}

也更新onSaveInstanceState

@Override
protected void onSaveInstanceState(Bundle outState)
{
    super.onSaveInstanceState(outState);
    wView.saveState(outState);
}

onRestoreInstanceState

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
    super.onRestoreInstanceState(savedInstanceState);
    wView.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>
于 2013-10-24T09:21:18.670 回答
22

在标签中(清单)

android:configChanges="orientation|screenSize"
于 2015-01-15T15:48:57.120 回答
15

添加android:configChanges="orientation|screenSize"清单对我有用

<activity
            android:name="com.example.HelloWorld.WebActivity"
            android:label="@string/title_activity_web"
            android:configChanges="orientation|screenSize" >
</activity>
于 2015-07-14T07:31:14.993 回答
8

我不相信这会再奏效了。在我的情况下,使用恢复状态WebView.restore(Bundle savedInstanceState)仍然会触发重新加载 url。

查看文档restoreState()您会看到它说:

如果在此 WebView 有机会建立状态(加载页面、创建后退/前进列表等)之后调用它,则可能会产生不良副作用。

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

向@e4c5 的道具在他的回答中指出我正确的方向

当然,极端的做法是防止方向变化触发活动破坏/创建。如何做到这一点的文档是here

于 2016-12-09T23:13:48.050 回答
7

在清单中添加此代码

<activity 
     ...
     android:configChanges="orientation|screenSize">
于 2014-08-25T16:00:39.490 回答
5

将其放在 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>
于 2017-10-05T14:34:34.543 回答
4

覆盖该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");
于 2014-03-18T11:20:13.810 回答
4

在你的清单文件中试试这个:

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
于 2017-10-05T11:12:12.327 回答
4

如此处所引

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

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

另外,请注意以下事项

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

于 2017-11-21T08:04:37.067 回答
4

这个解决方案对我很有效:

(1) 在 AndroidManifest.xml 中添加这一行 android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"

像这样(和上面的答案一样)

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

(2) 然后在 MainActivity.java 中验证 savedInstanceState

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mainContext = getApplicationContext();
    ----
    myWebView = (WebView) findViewById(R.id.webView);
    prepareWebView();
    myWebView.addJavascriptInterface(myJavaScriptInterface, "WEB2Android");

    if (savedInstanceState == null) {
        myWebView.post(new Runnable() {
            @Override
            public void run() {
                myWebView.loadUrl("http://www.appbiz.ro/foto_konta");
            }
        });
    }
    ----
}

(3) 然后:

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

@Override
protected void onSaveInstanceState(Bundle outState )
{
    super.onSaveInstanceState(outState);
    myWebView.saveState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
    super.onRestoreInstanceState(savedInstanceState);
    myWebView.restoreState(savedInstanceState);
}
于 2018-08-27T14:54:10.080 回答
0

在 Androidmanifest.xml 中添加:

<activity android:name=".MyActivity"
    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">

现在,当这些配置之一发生更改时,MyActivity不会重新启动。相反,MyActivity收到对 的调用onConfigurationChanged()

添加这个:

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

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    }
    else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
于 2020-03-01T09:44:53.920 回答