2012-08-26 9 views
52

Quando ruoto lo schermo, WebView ricarica l'intera pagina. Non posso avere questo dato che alcuni dei miei contenuti contengono materiale dinamico/casuale. Attualmente quando ruotato lo schermo ricarica l'URL originale dal metodo loadUrl().Android - Prevenzione di WebView ricarica su Rotate

Qualche idea di cosa non funziona nel mio codice?

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

Soluzione semplificata che ho utilizzato personalmente e che potrei raccomandare è qui: http://twigstechtips.blogspot.com/2013/08/android-retain-instance-of-webview.html –

risposta

59

Credo che il problema principale è che si chiama web.loadUrl (WebUrl); ! Anche quando savedInstanceState = null

EDIT

Prova:

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

EDIT2: È inoltre necessario l'onSaveInstanceState e di override 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); 
} 
+1

Sì! Questo funziona per me (dopo la modifica, Tim spotted!)! Grazie! Potresti spiegare perché e come funziona e perché quei metodi hanno bisogno di essere sovrascritti? – mark

+0

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

+0

Un'ultima cosa, ho davvero bisogno della seguente istruzione if: if (savedInstanceState! = Null) ((WebView) findViewById (R.id.web)) restoreState (savedInstanceState).; – mark

49

Nessun codice Java necessario. usa questo nel tuo file manifest.

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

come:

<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

di quali cambiamenti stai parlando? –

+0

in seguito al commento di @Mgamerz .. quando la materia sta girando .. questo è il peggior suggerimento che tu possa dare a –

+31

Noooooooooooo. Non pensare nemmeno a questo. Le modifiche alla configurazione non sono limitate alla rotazione. Inoltre, lo stato dell'istanza può essere ripristinato dopo essere tornato dalla memoria insufficiente. Il problema qui è che la configurazione non verrà aggiornata correttamente quando lo fai. Per favore, nessuno lo fa. –

2

l'override del metodo onConfigChange per evitare di ricaricare i dati sul cambiamento dell'orientamento

sulla vostra attività in AndroidMainfest file.

android:configChanges="orientation|keyboardHidden" 

e hanno questi come bene in WebView Impostazioni delle

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

aggiungere questo codice nel Manifesto

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

a tag (manifesto)

android:configChanges="orientation|screenSize" 

in classe

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

Non c'è in realtà alcun motivo per sovrascrivere il metodo '' 'onConfigurationChanged''' in quanto non è stata aggiunta alcuna funzionalità personalizzata. Fare semplicemente la modifica nel file manifest ha fatto il trucco per me. – i2097i

+0

Una risposta più completa: https://stackoverflow.com/a/46849736/454780 – trusktr

9

Aggiunta android:configChanges="orientation|screenSize" in opere manifesto per me

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

Puoi pubblicare cosa fa MainActivity riguardo a WebView? – trusktr

5

non credo che questo funzionerà più. Nel mio caso, il ripristino dello stato utilizzando WebView.restore(Bundle savedInstanceState) attiva comunque un ricarico dell'URL.

Guardando il docs per restoreState() vedrete che dice:

Se è chiamato dopo questo WebView ha avuto la possibilità di costruire lo stato (caricare le pagine, creare una/list avanti indietro, ecc) potrebbero esserci effetti collaterali indesiderati.

e

Si prega di notare che questo metodo non ripristina i dati di visualizzazione per questo WebView.

Props a @ e4c5 per avermi nella giusta direzione nella sua answer

E, naturalmente, l'estrema linea di condotta sarebbe quello di evitare modifiche di orientamento da innescare la distruzione di attività/creazione. La documentazione per sapere come fare questo è here

0

Prova questo nel vostro file manifesto:

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

Posizionare questa nell'attività file manifest.XML:

android:configChanges="orientation|screenSize" 

Ecco un esempio:

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

Come indicato here,

Attenzione: Cominciando con Android 3.2 (API di livello 13), la "dimensione dello schermo" cambia anche quando il dispositivo passa tra verticale e orizzontale orientamento. Pertanto, se si desidera impedire il riavvio del runtime a causa della modifica dell'orientamento durante lo sviluppo per il livello API 13 o successivo (come dichiarato dagli attributi minSdkVersion e targetSdkVersion), è necessario includere il valore "screenSize" oltre all'orientamento, . valore. Cioè, è necessario decalare android: configChanges = "orientation | screenSize". Tuttavia, se l'applicazione ha come target il livello API 12 o inferiore, l'attività sempre gestisce questa modifica della configurazione stessa (questa modifica di configurazione non riavvia l'attività, anche quando è in esecuzione su un dispositivo Android 3.2 o superiore).

impostazione android:configChanges="orientation|screenSize" sulla vostra attività risolverà questo problema.

Inoltre, prendere nota di quanto segue

Ricordate: Quando si dichiara la vostra attività per gestire una modifica alla configurazione , siete responsabili per ripristinare tutti gli elementi per i quali si fornire alternative. Se dichiari la tua attività per gestire la modifica dell'orientamento e immagini che dovrebbero cambiare tra orizzontale e verticale, devi riassegnare ogni risorsa a ciascun elemento durante onConfigurationChanged().