Android - Mencegah WebView dimuat ulang di Rotate

91

Saat saya memutar layar saya, WebView memuat ulang seluruh halaman. Saya tidak dapat memiliki ini karena beberapa konten saya mengandung materi dinamis / acak. Saat ini ketika diputar layar memuat ulang URL asli dari metode loadUrl ().

Tahu apa yang salah dengan kode saya?

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>
menandai
sumber
1
Solusi sederhana yang saya gunakan dan dapat saya rekomendasikan ada di sini: twigstechtips.blogspot.com/2013/08/…
Andrius Baruckis

Jawaban:

103

Saya pikir masalah utamanya adalah Anda memanggil web.loadUrl (webURL); juga saat disimpanInstanceState! = null

EDIT

Mencoba:

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

EDIT2 : Anda juga memerlukan penggantian onSaveInstanceState dan 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);
}

Catatan: Tambahkan juga AndroidManifest.xml Anda ke Aktivitas android: configChanges = "orientasi | screenSize" Terima kasih

Giuseppe
sumber
1
Iya! Ini bekerja untuk saya (setelah pengeditan, Tim melihat!)! Terima kasih! Bisakah Anda menjelaskan mengapa dan bagaimana ini bekerja dan mengapa metode tersebut perlu diganti?
tandai
Satu hal lagi, apakah saya benar-benar membutuhkan pernyataan-if berikut: if (storedInstanceState! = Null) ((WebView) findViewById (R.id.web)). RestoreState (storedInstanceState);
tandai
21
ini menyimpan halaman yang sama tetapi masih memuat ulang pada layar putar
Grasper
2
Ini berfungsi jika saya menambahkan properti android: configChanges ke <activity> di AndroidManifest, jadi dua hal dari jawaban Anda ditambah yang itu. Berikut jawaban yang lebih baik yang mencakup ketiga hal: stackoverflow.com/a/46849736/454780
trusktr
63

Pengkodean java tidak diperlukan. gunakan ini di file manifes Anda.

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

Suka:

<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>
Vettiyanakan
sumber
2
perubahan apa yang kamu bicarakan?
Pratik Poddar
mengikuti komentar @Mgamerz .. ketika masalah berputar .. ini adalah saran terburuk yang dapat Anda berikan
Guilherme Oliveira
54
Tidaaaaaaaaak. Jangan pernah berpikir untuk melakukan ini. Perubahan konfigurasi tidak terbatas pada rotasi. Selain itu, status instance dapat dipulihkan setelah kembali dari memori rendah. Masalahnya di sini adalah bahwa konfigurasi tidak akan diperbarui dengan benar saat Anda melakukan ini. Tolong, tidak ada yang melakukan ini.
Eric Cochran
6
@EricCochran Bisakah Anda menulis jawaban yang benar, jika Anda tahu? Jawaban yang diterima masih memuat ulang halaman untuk saya, juga kehilangan info sesi. Yang dalam kasus saya seperti wow, Anda menghidupkan telepon - Anda harus masuk lagi.
Atomosk
Ini mungkin hanya sebagian dari jawaban lengkap. Lihat yang lebih baik ini: stackoverflow.com/a/46849736/454780
trusktr
20

dalam tag (manifes)

android:configChanges="orientation|screenSize"
01wifi01
sumber
9
Sebenarnya tidak ada alasan untuk mengganti onConfigurationChangedmetode karena tidak ada fungsi khusus yang ditambahkan. Cukup membuat perubahan pada file manifes sudah melakukan trik bagi saya.
i2097i
manifes sudah cukup, dan upvote hanya untuk menambahkanorientation|screenSize
Varun Garg
14

Menambahkan android:configChanges="orientation|screenSize"karya manifes untuk saya

<activity
            android:name="com.example.HelloWorld.WebActivity"
            android:label="@string/title_activity_web"
            android:configChanges="orientation|screenSize" >
</activity>
Rasel
sumber
Dapatkah Anda memposting apa yang dilakukan MainActivity Anda terkait WebView?
trusktr
8

Saya tidak percaya ini akan berhasil lagi. Dalam kasus saya, memulihkan status menggunakanWebView.restore(Bundle savedInstanceState) masih memicu pemuatan ulang url.

Melihat dokumen untuk restoreState()Anda akan melihatnya mengatakan:

Jika dipanggil setelah WebView ini memiliki kesempatan untuk membangun status (memuat halaman, membuat daftar mundur / maju, dll.) Mungkin ada efek samping yang tidak diinginkan.

dan

Harap perhatikan bahwa metode ini tidak lagi mengembalikan data tampilan untuk WebView ini.

Properti untuk @ e4c5 karena mengarahkan saya ke arah yang benar dalam jawabannya

Dan tentu saja, tindakan ekstrem adalah mencegah perubahan orientasi yang memicu perusakan / penciptaan aktivitas. Dokumentasi cara melakukannya ada di sini

Ranjeev Mahtani
sumber
6

Tambahkan kode ini di Manifest

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

Ganti onConfigChangemetode untuk menghindari memuat ulang data saat orientasi berubah

tentang aktivitas Anda di AndroidMainfestfile.

android:configChanges="orientation|keyboardHidden" 

dan memilikinya juga di setelan Tampilan Web Anda

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

Coba ini di file manifes Anda:

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
Ajeet Yadav
sumber
4

Tempatkan ini di aktivitas file Manifest.xml:

android:configChanges="orientation|screenSize"

Berikut ini contohnya:

<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>
Carlos Alberto Gonzalez
sumber
4

Seperti dikutip di sini ,

Perhatian: Mulai Android 3.2 (API level 13), "ukuran layar" juga berubah saat perangkat beralih antara orientasi potret dan lanskap. Jadi, jika Anda ingin mencegah waktu proses dimulai ulang karena perubahan orientasi saat mengembangkan API level 13 atau yang lebih tinggi (seperti yang dideklarasikan oleh atribut minSdkVersion dan targetSdkVersion), Anda harus menyertakan nilai "screenSize" selain nilai "orientasi". Artinya, Anda harus mendeklarasikan android: configChanges = "orientasi | screenSize". Namun, jika aplikasi Anda menargetkan API level 12 atau yang lebih rendah, aktivitas Anda selalu menangani perubahan konfigurasi ini sendiri (perubahan konfigurasi ini tidak memulai ulang aktivitas Anda, bahkan saat dijalankan pada perangkat Android 3.2 atau yang lebih tinggi).

pengaturan android:configChanges="orientation|screenSize" pada aktivitas Anda akan menyelesaikan masalah ini.

Perhatikan juga hal-hal berikut ini

Ingat: Ketika Anda mendeklarasikan aktivitas Anda untuk menangani perubahan konfigurasi, Anda bertanggung jawab untuk menyetel ulang setiap elemen yang Anda berikan alternatifnya. Jika Anda mendeklarasikan aktivitas Anda untuk menangani perubahan orientasi dan memiliki gambar yang harus berubah antara lanskap dan potret, Anda harus menetapkan ulang setiap sumber daya ke setiap elemen selama onConfigurationChanged ().

davejoem
sumber
3

Solusi ini bekerja dengan baik untuk saya:

(1) Di AndroidManifest.xml tambahkan baris ini android: configChanges = "keyboard | keyboardHidden | orientasi | screenLayout | uiMode | screenSize | terkecilScreenSize"

Seperti ini (dan seperti jawaban di atas)

<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) Kemudian di MainActivity.java verifikasi disimpanInstanceState

@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) dan kemudian:

@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);
}
Adrian S.
sumber
0

Tambahkan ini di Androidmanifest.xml:

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

Sekarang, ketika salah satu dari konfigurasi ini berubah, MyActivitytidak restart. Sebaliknya, MyActivitymenerima panggilan ke onConfigurationChanged().

Tambahkan ini:

@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();
    }
}
Cerah Singh
sumber