Подтвердить что ты не робот

Android - предотвращение перезагрузки WebView при повороте

Когда я поворачиваю свой экран, WebView перезагружает всю страницу. Я не могу этого сделать, поскольку некоторые из моих материалов содержат динамический/случайный материал. В настоящее время при повороте экран перезагружает исходный URL-адрес из метода loadUrl().

Любая идея, что не так с моим кодом?

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>
4b9b3361

Ответ 1

Я думаю, что основная проблема в том, что вы вызываете web.loadUrl(webURL); также при сохранении InstanceState! = 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);
}

Примечание. Пожалуйста, добавьте также свой AndroidManifest.xml в свой Android-активность: configChanges = "direction | screenSize". Спасибо

Ответ 2

Нет необходимости кодирования 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>

Ответ 3

в теге (манифест)

android:configChanges="orientation|screenSize"

Ответ 4

Добавление android:configChanges="orientation|screenSize" в манифест работает для меня

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

Ответ 5

Я не верю, что это сработает. В моем случае восстановление состояния с помощью WebView.restore(Bundle savedInstanceState) по-прежнему вызывает перезагрузку URL-адреса.

Глядя на docs для restoreState(), вы увидите, что он говорит:

Если он вызывается после того, как этот WebView имел возможность построить состояние (загружать страницы, создать список назад/вперед и т.д.), могут быть нежелательные побочные эффекты.

и

Обратите внимание, что этот метод больше не восстанавливает данные отображения для этого WebView.

Подставляет к @e4c5 для указания меня в правильном направлении в ответе

И, конечно же, экстремальный ход действий будет заключаться в том, чтобы предотвратить изменение ориентации от запуска или уничтожения активности. Документация о том, как это сделать, здесь

Ответ 6

Добавьте этот код в манифест

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

Ответ 7

Переопределите метод 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");

Ответ 8

Попробуйте это в файле манифеста:

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

Ответ 9

Поместите это в действие файла 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>

Ответ 10

Как указано здесь,

Внимание: начиная с Android 3.2 (уровень API 13), размер экрана "также изменяется, когда устройство переключается между портретным и ландшафтным ориентации. Таким образом, если вы хотите предотвратить перезагрузки во время выполнения из-за изменение ориентации при разработке для уровня API 13 или выше (как объявленные атрибутами minSdkVersion и targetSdkVersion), вы должен включать значение" screenSize "в дополнение к" ориентации ", стоимость. То есть, вы должны декалировать андроид: configChanges =" ориентация | Размер экрана". Однако, если ваш приложение нацеливается на уровень API 12 или ниже, тогда ваша деятельность всегда обрабатывает это изменение конфигурации (это изменение конфигурации не перезапускает вашу активность, даже при работе на Android 3.2 или более высокое устройство).

android:configChanges="orientation|screenSize" в вашей деятельности разрешит эту проблему.

Также обратите внимание на следующее

Помните: когда вы объявляете свою активность для обработки конфигурации изменения, вы несете ответственность за сброс любых элементов, для которых вы предоставлять альтернативы. Если вы заявляете, что ваша деятельность обрабатывает изменение ориентации и изображения, которые должны пейзаж и портрет, вы должны переназначить каждый ресурс для каждого элемент во время onConfigurationChanged().

Ответ 11

Это решение хорошо работает для меня:

(1) В AndroidManifest.xml добавьте эту строку android: configChanges = "клавиатура | клавиатура скрытая | ориентация | screenLayout | uiMode | screenSize | smalllestScreenSize"

Как это (и как ответы выше)

<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 подтвердите сохраненный_инстанс

@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);
}