Android - Empêcher le rechargement de WebView lors de la rotation


90

Lorsque je fais pivoter mon écran, WebView recharge toute la page. Je ne peux pas avoir cela car une partie de mon contenu contient du matériel dynamique / aléatoire. Actuellement, lors de la rotation, l'écran recharge l'URL d'origine à partir de la méthode loadUrl ().

Une idée de ce qui ne va pas avec mon code?

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>

1
La solution simplifiée que j'ai utilisée moi-même et que je pourrais recommander est ici: twigstechtips.blogspot.com/2013/08/…
Andrius Baruckis

Réponses:


103

Je pense que le principal problème est que vous appelez web.loadUrl (webURL); également lorsque savedInstanceState! = null

ÉDITER

Essayer:

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

EDIT2 : Vous avez également besoin du remplacement onSaveInstanceState et 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);
}

Remarque: veuillez également ajouter votre AndroidManifest.xml dans votre activité android: configChanges = "orientation | screenSize" Merci


1
Oui! Cela fonctionne pour moi (après le montage, Tim l'a repéré!)! Merci! Pourriez-vous expliquer pourquoi et comment cela fonctionne et pourquoi ces méthodes devaient être remplacées?
marque


Une dernière chose, ai-je vraiment besoin de l'instruction if suivante: if (savedInstanceState! = Null) ((WebView) findViewById (R.id.web)). RestoreState (savedInstanceState);
marque

21
cela garde la même page mais toujours recharger sur la rotation de l'écran
Grasper

2
Cela fonctionne si j'ajoute la propriété android: configChanges à <activity> dans AndroidManifest, donc les deux choses de votre réponse plus celle-là. Voici une meilleure réponse qui comprend les trois choses: stackoverflow.com/a/46849736/454780
trusktr

63

Aucun codage Java nécessaire. utilisez ceci dans votre fichier manifeste.

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

comme:

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

2
de quels changements parlez-vous?
Pratik Poddar

suite au commentaire de @Mgamerz .. quand le sujet tourne .. c'est la pire suggestion que vous puissiez donner
Guilherme Oliveira

54
Noooooooooooo. Ne pensez même pas à faire ça. Les changements de configuration ne se limitent pas à la rotation. En outre, l'état de l'instance peut être restauré après être revenu d'une mémoire insuffisante. Le problème ici est que la configuration ne sera pas mise à jour correctement lorsque vous effectuez cette opération. S'il vous plaît, personne ne fait ça.
Eric Cochran

6
@EricCochran Pourriez-vous écrire la bonne réponse, si vous en connaissez une? La réponse acceptée recharge toujours la page pour moi, ainsi que les informations de session. Ce qui dans mon cas est comme wow, vous allumez le téléphone - vous devez vous reconnecter.
Atomosk

Cela ne peut faire partie que d'une réponse complète. Voir ce meilleur: stackoverflow.com/a/46849736/454780
trusktr

19

dans la balise (manifeste)

android:configChanges="orientation|screenSize"

8
Il n'y a en fait aucune raison de remplacer la onConfigurationChangedméthode car aucune fonctionnalité personnalisée n'est ajoutée. Le simple fait de modifier le fichier manifeste a fait l'affaire pour moi.
i2097i

manifeste était suffisant, et vote favorable pour l'ajout uniquementorientation|screenSize
Varun Garg

14

L'ajout android:configChanges="orientation|screenSize"de manifeste fonctionne pour moi

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

Pouvez-vous publier ce que fait votre MainActivity concernant la WebView?
trusktr

8

Je ne pense pas que cela fonctionnera plus. Dans mon cas, la restauration de l'état à l'aide de WebView.restore(Bundle savedInstanceState)déclenche toujours un rechargement de l'url.

En regardant les documents pour restoreState()vous le verrez dit:

Si elle est appelée après que cette WebView ait eu la possibilité de générer l'état (charger des pages, créer une liste précédente / suivante, etc.), il peut y avoir des effets secondaires indésirables.

et

Veuillez noter que cette méthode ne restaure plus les données d'affichage pour cette WebView.

Props à @ e4c5 pour m'avoir pointé dans la bonne direction dans sa réponse

Et bien sûr, la ligne de conduite extrême serait d'empêcher les changements d'orientation de déclencher la destruction / création d'activité. La documentation pour savoir comment faire est ici


6

Ajouter ce code dans le manifeste

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

4

Remplacer la onConfigChangeméthode pour éviter de recharger les données lors du changement d'orientation

sur votre activité dans le AndroidMainfestfichier.

android:configChanges="orientation|keyboardHidden" 

et les avoir également dans vos paramètres WebView

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

4

Essayez ceci dans votre fichier manifeste:

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

4

Placez ceci dans l'activité du fichier Manifest.xml:

android:configChanges="orientation|screenSize"

Voici un exemple:

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

4

Comme cité ici ,

Attention: à partir d'Android 3.2 (niveau d'API 13), la «taille de l'écran» change également lorsque l'appareil bascule entre l'orientation portrait et paysage. Ainsi, si vous souhaitez empêcher le redémarrage de l'exécution en raison d'un changement d'orientation lors du développement pour le niveau d'API 13 ou supérieur (comme déclaré par les attributs minSdkVersion et targetSdkVersion), vous devez inclure la valeur "screenSize" en plus de la valeur "orientation". Autrement dit, vous devez decalare android: configChanges = "orientation | screenSize". Cependant, si votre application cible le niveau d'API 12 ou inférieur, votre activité gère toujours cette modification de configuration elle-même (cette modification de configuration ne redémarre pas votre activité, même lorsqu'elle est exécutée sur un appareil Android 3.2 ou supérieur).

le paramétrage android:configChanges="orientation|screenSize"de votre activité résoudra ce problème.

Prenez également note de ce qui suit

N'oubliez pas: lorsque vous déclarez votre activité pour gérer un changement de configuration, vous êtes responsable de la réinitialisation de tous les éléments pour lesquels vous fournissez des alternatives. Si vous déclarez votre activité pour gérer le changement d'orientation et que vous avez des images qui devraient changer entre paysage et portrait, vous devez réattribuer chaque ressource à chaque élément pendant onConfigurationChanged ().


3

Cette solution fonctionne bien pour moi:

(1) Dans AndroidManifest.xml, ajoutez cette ligne android: configChanges = "keyboard | keyboardHidden | orientation | screenLayout | uiMode | screenSize | smallestScreenSize"

Comme ça (et comme les réponses ci-dessus)

<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) Puis dans MainActivity.java, vérifiez 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) puis:

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

0

Ajoutez ceci dans Androidmanifest.xml:

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

Maintenant, lorsque l'une de ces configurations change, MyActivityne redémarre pas. Au lieu de cela, MyActivityreçoit un appel à onConfigurationChanged().

Ajoute ça:

@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();
    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.