Android - Döndürmede Web Görünümünün yeniden yüklenmesini önleme


91

Ekranımı döndürdüğümde, WebView tüm sayfayı yeniden yüklüyor. İçeriğimin bir kısmı dinamik / rastgele materyal içerdiğinden buna sahip olamıyorum. Şu anda döndürüldüğünde ekran, loadUrl () yönteminden orijinal URL'yi yeniden yükler.

Kodumun nesi var fikriniz var mı?

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>

Yanıtlar:


103

Sanırım asıl sorun web.loadUrl (webURL) 'i çağırmanız; ayrıca kaydedildiğindeInstanceState! = null

DÜZENLE

Deneyin:

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

EDIT2 : Ayrıca onSaveInstanceState ve onRestoreInstanceState geçersiz kılma işlemlerine de ihtiyacınız var.

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

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

Not: Lütfen AndroidManifest.xml dosyanızı Aktivite androidinize ekleyin: configChanges = "orientation | screenSize" Teşekkürler


1
Evet! Bu benim için çalışıyor (düzenlemeden sonra Tim fark etti!)! Teşekkür ederim! Bunun neden ve nasıl çalıştığını ve neden bu yöntemlerin geçersiz kılınması gerektiğini açıklayabilir misiniz?
işaretleyin


Son bir şey, gerçekten şu if ifadesine ihtiyacım var mı: if (SavedInstanceState! = Null) ((WebView) findViewById (R.id.web)). RestoreState (SavedInstanceState);
mark

21
bu aynı sayfayı
koruyor

2
AndroidManifest'teki <activity> öğesine android: configChanges özelliğini eklersem bu işe yarar, yani cevabınızdaki iki şey artı o. İşte üç şeyi de içeren daha iyi bir cevap: stackoverflow.com/a/46849736/454780
trusktr

63

Java kodlamasına gerek yok. bunu manifest dosyanızda kullanın.

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

sevmek:

<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
hangi değişikliklerden bahsediyorsun?
Pratik Poddar

@Mgamerz yorumunu takiben .. konu dönerken .. bu verebileceğiniz en kötü öneri
Guilherme Oliveira

54
Noooooooooooo. Bunu yapmayı düşünme bile. Yapılandırma değişiklikleri rotasyonla sınırlı değildir. Ayrıca, örnek durumu düşük bellekten geri döndükten sonra geri yüklenebilir. Buradaki sorun, bunu yaptığınızda konfigürasyonun doğru şekilde güncellenmeyecek olmasıdır. Lütfen bunu kimse yapmasın.
Eric Cochran

6
@EricCochran Biliyorsanız doğru cevabı yazabilir misiniz? Kabul edilen cevap hala benim için sayfayı yeniden yüklüyor, ayrıca oturum bilgilerini kaybediyor. Bu benim durumumda vay gibi, telefonu çeviriyorsun - tekrar giriş yapmalısın.
Atomosk

Bu yalnızca tam bir cevabın parçası olabilir.
Şunu

20

etikette (bildirim)

android:configChanges="orientation|screenSize"

9
onConfigurationChangedHiçbir özel işlev eklenmediğinden , yöntemi geçersiz kılmak için hiçbir neden yoktur. Sadece manifest dosyasında değişiklik yapmak benim için hile yaptı.
i2097i

manifest yeterliydi ve yalnızca ekleme için oy verinorientation|screenSize
Varun Garg

14

android:configChanges="orientation|screenSize"Manifest'e eklemek benim için çalışıyor

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

MainActivity'nizin WebView ile ilgili ne yaptığını yayınlayabilir misiniz?
trusktr

8

Bunun artık işe yarayacağına inanmıyorum. Benim durumumda, durumu kullanarak geri yükleme WebView.restore(Bundle savedInstanceState)hala url'nin yeniden yüklenmesini tetikliyor.

Baktığımızda docs için restoreState()yazdığını göreceksiniz:

Bu WebView durum oluşturma şansı bulduktan sonra çağrılırsa (sayfaları yükleme, bir geri / ileri listesi oluşturma, vb.) İstenmeyen yan etkiler olabilir.

ve

Lütfen bu yöntemin artık bu Web Görünümü için görüntü verilerini geri yüklemediğini unutmayın.

Onun içinde doğru yönde beni işaret için @ e4c5 Dikmeler cevap

Ve tabii ki, en uç eylem planı, yönelim değişikliklerinin aktivite yıkımını / yaratımını tetiklemesini önlemek olacaktır. Bunun nasıl yapılacağına dair belgeler burada


6

Bu kodu Manifest'e ekle

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

4

Yön onConfigChangedeğişikliğinde verilerin yeniden yüklenmesini önlemek için yöntemi geçersiz kılın

AndroidMainfestdosyadaki aktiviteniz hakkında .

android:configChanges="orientation|keyboardHidden" 

ve bunları Web Görünümü ayarlarınızda da bulundurun

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

4

Bunu manifest dosyanızda deneyin:

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

4

Bunu Manifest.xml dosyası etkinliğine yerleştirin:

android:configChanges="orientation|screenSize"

İşte bir örnek:

<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

Alıntılanan gibi burada ,

Dikkat: Android 3.2'den (API seviyesi 13) başlayarak, "ekran boyutu" da cihaz dikey ve yatay yön arasında geçiş yaptığında değişir. Bu nedenle, API seviyesi 13 veya üstü için geliştirme yaparken yön değişikliği nedeniyle çalışma zamanının yeniden başlatılmasını önlemek istiyorsanız (minSdkVersion ve targetSdkVersion öznitelikleri tarafından bildirildiği gibi), "yönlendirme" değerine ek olarak "screenSize" değerini de eklemeniz gerekir. Yani, android: configChanges = "orientation | screenSize" değerini onarmalısınız. Ancak, uygulamanız API düzeyi 12 veya altını hedefliyorsa, etkinliğiniz her zaman bu yapılandırma değişikliğini kendisi ele alır (bu yapılandırma değişikliği, Android 3.2 veya üzeri bir cihazda çalışırken bile etkinliğinizi yeniden başlatmaz).

android:configChanges="orientation|screenSize"etkinliğinizi ayarlamak bu sorunu çözecektir.

Ayrıca aşağıdakilere de dikkat edin

Unutmayın: Aktivitenizin bir konfigürasyon değişikliğini idare edeceğini beyan ettiğinizde, alternatif sağladığınız tüm öğeleri sıfırlamaktan siz sorumlusunuz. Aktivitenizin oryantasyon değişikliğini işleyeceğini bildirirseniz ve yatay ile dikey arasında değişmesi gereken resimleriniz varsa, onConfigurationChanged () sırasında her bir kaynağı her bir öğeye yeniden atamanız gerekir.


3

Bu çözüm benim için iyi çalışıyor:

(1) AndroidManifest.xml'de şu satırı ekleyin android: configChanges = "keyboard | keyboardHidden | orientation | screenLayout | uiMode | screenSize | smallestScreenSize"

Bunun gibi (ve yukarıdaki cevaplar gibi)

<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) Ardından MainActivity.java'da kaydedilenInstanceState'i doğrulayın

@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) ve sonra:

@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

Bunu Androidmanifest.xml'e ekleyin:

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

Şimdi, bu konfigürasyonlardan biri değiştiğinde MyActivityyeniden başlamıyor. Bunun yerine, MyActivitybir çağrı alır onConfigurationChanged().

Bunu ekle:

@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();
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.