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>

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


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>

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"

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>

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


6

Tambahkan kode ini di Manifest

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

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");

4

Coba ini di file manifes Anda:

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

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>

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 ().


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

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();
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.