2012-08-26 17 views
52

Wenn ich meinen Bildschirm rotiere, lädt das WebView die ganze Seite neu. Ich kann das nicht haben, da einige meiner Inhalte dynamisches/zufälliges Material enthalten. Wenn der Bildschirm gedreht wird, wird der ursprüngliche URL von der loadUrl() -Methode neu geladen.Android - Verhindern, dass WebView beim Rotieren neu geladen wird

Irgendeine Idee, was mit meinem Code falsch ist?

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

Vereinfachte Lösung, die ich selbst verwendet habe und empfehlen könnte, ist hier: http://twigstechtips.blogspot.com/2013/08/android-retaine-instance-of-webview.html –

Antwort

59

denke ich, das Hauptproblem ist, dass Sie rufen web.loadUrl (WebUrl); ! Auch wenn savedInstanceState = null

EDIT

Versuchen:

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

EDIT2: Sie müssen auch die onSaveInstanceState und onRestoreInstanceState außer Kraft setzen.

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

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{ 
super.onRestoreInstanceState(savedInstanceState); 
web.restoreState(savedInstanceState); 
} 
+1

Ja! Das funktioniert für mich (nach der Bearbeitung, Tim entdeckt!)! Vielen Dank! Könnten Sie vielleicht erklären, warum und wie das funktioniert und warum diese Methoden Vorrang haben? – mark

+0

@mark siehe http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges – Giuseppe

+0

Eine letzte Sache, brauche ich wirklich die folgende if-Anweisung: if (savedInstanceState! = Null) (((WebView) findViewById (R.id.web)). RestoreState (savedInstanceState); – mark

49

Keine Java-Codierung benötigt. Verwenden Sie dies in Ihrer Manifestdatei.

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

wie:

<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

über welche Änderungen sprechen Sie? –

+0

folgende @Mgamerz Kommentar .. wenn die Sache dreht .. das ist der schlechteste Vorschlag, den Sie geben können –

+31

Nooooooooooooo. Denk nicht mal darüber nach. Konfigurationsänderungen sind nicht auf die Rotation beschränkt. Außerdem kann der Instanzstatus wiederhergestellt werden, nachdem er aus dem niedrigen Speicherbereich zurückgekehrt ist. Das Problem hierbei ist, dass die Konfiguration nicht korrekt aktualisiert wird, wenn Sie dies tun. Bitte, niemand tut das. –

2

Aufschalten der onConfigChange Methode zu vermeiden, dass Daten auf Orientierungsänderung

auf Ihrer Aktivität in AndroidMainfest Datei neu zu laden.

android:configChanges="orientation|keyboardHidden" 

und haben diese auch in Ihrer WebView-Einstellungen

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

diesen Code hinzufügen in Manifest

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

in Tag (Manifest)

android:configChanges="orientation|screenSize" 

in der Klasse

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

Es gibt eigentlich keinen Grund, die '' 'onConfigurationChanged''' Methode zu überschreiben, da keine benutzerdefinierte Funktionalität hinzugefügt wurde. Einfach die Änderung in der Manifest-Datei vorzunehmen, hat sich für mich gelohnt. – i2097i

+0

Eine vollständigere Antwort: https://Stackoverflow.com/a/46849736/454780 – trusktr

9

android:configChanges="orientation|screenSize" in manifest Werke Hinzufügen für mich

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

Können Sie posten, was Ihre MainActivity in Bezug auf das WebView tut? – trusktr

5

Ich glaube nicht, das mehr funktionieren wird. In meinem Fall löst der Wiederherstellungsstatus unter Verwendung von WebView.restore(Bundle savedInstanceState) immer noch ein Neuladen der URL aus.

Mit Blick auf die docs für restoreState() Sie werden sehen, es sagt:

Wenn es aufgerufen wird, nachdem diese WebView eine Chance zu bauen Zustand (Last Seiten hatte, erstellen Sie eine Vor/Zurück-Liste, usw.) kann es unerwünschte Nebenwirkungen geben.

und

Bitte beachten Sie, dass diese Methode nicht mehr die Anzeigedaten für dieses WebView wieder her.

Props an @ e4c5 für mich in die richtige Richtung zeigt, in seiner answer

Und natürlich würde die extreme Vorgehensweise sein, um Orientierungsänderungen verhindert das Auslösen Aktivität Zerstörung/Schöpfung. Dokumentation nach, wie dies zu tun ist here

0

Versuchen Sie dies in Ihrer Manifest-Datei:

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

Dieses in der Manifest.xml Datei Aktivität:

android:configChanges="orientation|screenSize" 

Hier ein Beispiel:

1

Wie zitiert here,

Vorsicht: Beginnend mit Android 3.2 (API-Ebene 13), der „Bildgröße“ ändert sich auch, wenn das Gerät schaltet zwischen Hoch- und Quer Orientierung. Wenn Sie also Laufzeitneustarts aufgrund von Orientierungsänderungen bei der Entwicklung für API-Stufe 13 oder höher (wie durch die Attribute minSdkVersion und targetSdkVersion deklariert) verhindern möchten, müssen Sie zusätzlich zur "Ausrichtung" den Wert "screenSize" einfügen. Wert. Das heißt, Sie müssen android dekonfigurieren: configChanges = "orientation | screenSize". Wenn Ihre -Anwendung jedoch API-Ebene 12 oder niedriger anwendet, verarbeitet Ihre Aktivität immer diese Konfigurationsänderung selbst (diese Konfigurationsänderung startet Ihre Aktivität nicht neu, auch wenn sie auf einem Android 3.2 oder höheren Gerät ausgeführt wird).

Einstellung android:configChanges="orientation|screenSize" auf Ihre Aktivität wird dieses Problem beheben.

Auch beachten Sie die folgenden

Denken Sie daran: Wenn Sie Ihre Tätigkeit deklarieren eine Konfiguration Änderung zu handhaben, sind Sie alle Elemente für das Zurücksetzen verantwortlich für die Sie Alternativen bieten . Wenn Sie Ihre Aktivität für die Bearbeitung der Orientierungsänderung definieren und Bilder zwischen Querformat und Hochformat ändern, müssen Sie jede Ressource während onConfigurationChanged() jedem Element neu zuweisen.

Verwandte Themen