Android Web Görünümü - Önbelleği Tamamen Temizle


111

Etkinliklerimden birinde bir Web Görünümü var ve bir web sayfasını yüklediğinde, sayfa Facebook'tan bazı arka plan verileri toplar.

Yine de gördüğüm şey, uygulamada görüntülenen sayfanın, uygulama her açıldığında ve yenilendiğinde aynı olması.

Web Görünümü'nü önbelleği kullanmayacak şekilde ayarlamayı ve Web Görünümü önbelleğini ve geçmişini temizlemeyi denedim.

Ayrıca buradaki öneriyi de takip ettim: WebView için önbellek nasıl boşaltılır?

Ama bunların hiçbiri işe yaramıyor, kimsenin bu sorunun üstesinden gelebileceğime dair herhangi bir fikri yok, çünkü bu başvurumun hayati bir parçası.

    mWebView.setWebChromeClient(new WebChromeClient()
    {
           public void onProgressChanged(WebView view, int progress)
           {
               if(progress >= 100)
               {
                   mProgressBar.setVisibility(ProgressBar.INVISIBLE);
               }
               else
               {
                   mProgressBar.setVisibility(ProgressBar.VISIBLE);
               }
           }
    });
    mWebView.setWebViewClient(new SignInFBWebViewClient(mUIHandler));
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.clearHistory();
    mWebView.clearFormData();
    mWebView.clearCache(true);

    WebSettings webSettings = mWebView.getSettings();
    webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

    Time time = new Time();
    time.setToNow();

    mWebView.loadUrl(mSocialProxy.getSignInURL()+"?time="+time.format("%Y%m%d%H%M%S"));

Bu yüzden ilk öneriyi uyguladım (Kodu özyinelemeli olacak şekilde değiştirmesine rağmen)

private void clearApplicationCache() {
    File dir = getCacheDir();

    if (dir != null && dir.isDirectory()) {
        try {
            ArrayList<File> stack = new ArrayList<File>();

            // Initialise the list
            File[] children = dir.listFiles();
            for (File child : children) {
                stack.add(child);
            }

            while (stack.size() > 0) {
                Log.v(TAG, LOG_START + "Clearing the stack - " + stack.size());
                File f = stack.get(stack.size() - 1);
                if (f.isDirectory() == true) {
                    boolean empty = f.delete();

                    if (empty == false) {
                        File[] files = f.listFiles();
                        if (files.length != 0) {
                            for (File tmp : files) {
                                stack.add(tmp);
                            }
                        }
                    } else {
                        stack.remove(stack.size() - 1);
                    }
                } else {
                    f.delete();
                    stack.remove(stack.size() - 1);
                }
            }
        } catch (Exception e) {
            Log.e(TAG, LOG_START + "Failed to clean the cache");
        }
    }
}

Ancak bu, sayfanın görüntülediği şeyi hala değiştirmedi. Masaüstü tarayıcımda WebView'da üretilen web sayfasına farklı html kodu alıyorum, bu nedenle WebView’un bir yerde önbelleğe alması gerektiğini biliyorum.

IRC kanalında, bir URL Bağlantısından önbelleğe almayı kaldırmak için bir düzeltmeye yönlendirildim, ancak henüz bir WebView'a nasıl uygulanacağını göremiyorum.

http://www.androidsnippets.org/snippets/45/

Uygulamamı silip yeniden yüklersem, web sayfasını, yani önbelleğe alınmamış bir sürümü, güncelleyebilirim. Temel sorun, web sayfasındaki bağlantılarda yapılan değişikliklerin web sayfasının ön ucunun tamamen değişmemiş olmasıdır.


1
mWebView.getSettings().setAppCacheEnabled(false);çalışmadı mı?
Paul

Yanıtlar:


45

Gaunt Face tarafından yayınlanan yukarıdaki düzenlenmiş kod parçacığı, dosyalarından biri silinemediği için bir dizin silinemezse, kodun sonsuz bir döngüde yeniden denemeye devam edeceği şeklinde bir hata içerir. Gerçekten özyinelemeli olması için yeniden yazdım ve bir numDays parametresi ekledim, böylece budanmış dosyaların kaç yaşında olması gerektiğini kontrol edebilirsiniz:

//helper method for clearCache() , recursive
//returns number of deleted files
static int clearCacheFolder(final File dir, final int numDays) {

    int deletedFiles = 0;
    if (dir!= null && dir.isDirectory()) {
        try {
            for (File child:dir.listFiles()) {

                //first delete subdirectories recursively
                if (child.isDirectory()) {
                    deletedFiles += clearCacheFolder(child, numDays);
                }

                //then delete the files and subdirectories in this dir
                //only empty directories can be deleted, so subdirs have been done first
                if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
                    if (child.delete()) {
                        deletedFiles++;
                    }
                }
            }
        }
        catch(Exception e) {
            Log.e(TAG, String.format("Failed to clean the cache, error %s", e.getMessage()));
        }
    }
    return deletedFiles;
}

/*
 * Delete the files older than numDays days from the application cache
 * 0 means all files.
 */
public static void clearCache(final Context context, final int numDays) {
    Log.i(TAG, String.format("Starting cache prune, deleting files older than %d days", numDays));
    int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays);
    Log.i(TAG, String.format("Cache pruning completed, %d files deleted", numDeletedFiles));
}

Umarım diğer insanlara faydası olur :)


Çok teşekkürler! siz benim günümü kurtardınız :)
Kris

Harika bir rutin, bizi çok fazla ızdıraptan kurtardı.
Mr Ed

Telefonumda yüklü belirli uygulamaların önbelleğini temizlemek için bu kodu bir uygulama içinde kullanabilir miyim?
Si8

Tüm dizinin silinmesi gerekiyorsa, Runtime.getRuntime (). Exec ("rm -rf" + dirName + "\ n"); daha kolay ol?
source.rar

@ source.rar Evet, ancak bu durumda dosyaları x günden daha genç tutma olanağınız yoktur, bu genellikle bir önbellek klasörü için tercih edersiniz.
markjan

205

Önbelleği temizlemek için daha da zarif ve basit bir çözüm buldum

WebView obj;
obj.clearCache(true);

http://developer.android.com/reference/android/webkit/WebView.html#clearCache%28boolean%29

Önbelleği temizlemenin yolunu bulmaya çalışıyordum, ancak yukarıda belirtilen yöntemlerden yapabileceğimiz tek şey yerel dosyaları kaldırmaktı, ancak RAM'i asla temizlemedi.

API clearCache, web görünümü tarafından kullanılan RAM'i serbest bırakır ve bu nedenle web sayfasının yeniden yüklenmesini zorunlu kılar.


11
Buradaki en iyi cevap.
user486134

En iyi cevap ve neden kabul edilmediğini merak ediyorum..Kudos Akshat :)
Karthik

1
Benim için şans yok. Bir şeyin değişip değişmediğini merak ediyor musunuz? Google.com ile bir Web Görünümü yükleyebilirim ve Web Görünümü, clearCache (true) işleminden sonra bile hala oturum açtığımı düşünüyor;
lostintranslation

2
@lostintranslation Bunun için muhtemelen çerezleri silmek istiyorsunuz. Şimdiye kadar öğrendiğine eminim.
NineToeNerd

Nesneyi ayırmanız mı gerekiyor? WebView obj = new WebView (bu); obj.clearCache (doğru); Her neyse, benim için çok iyi, oy verildi!
Giorgio Barchiesi

45

Aradığınız düzeltmeyi buldum:

context.deleteDatabase("webview.db");
context.deleteDatabase("webviewCache.db");

Bazı nedenlerden dolayı Android, ihtiyaç duyduğunuz yeni veriler yerine yanlışlıkla geri dönmeye devam ettiği url'nin kötü bir önbelleğini oluşturur. Elbette, girişleri DB'den silebilirsiniz, ancak benim durumumda yalnızca bir URL'ye erişmeye çalışıyorum, böylece tüm DB'yi uçurmak daha kolay.

Ve endişelenmeyin, bu DB'ler yalnızca uygulamanızla ilişkilendirildiğinden tüm telefonun önbelleğini temizlemiyorsunuz.


Teşekkürler, bu inanılmaz derecede güzel bir numara. Daha yaygın olarak bilinmeyi hak ediyor.
Philip Sheard

2
Bu, petek: 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): Veritabanını açmada kötü bir istisna atar. kapatıyorum. 06-14 22: 33: 34.349: HATA / SQLiteDatabase (20382): android.database.sqlite.SQLiteDiskIOException: disk G / Ç hatası 06-14 22: 33: 34.349: HATA / SQLiteDatabase (20382): android.database. sqlite.SQLiteDatabase.native_setLocale (Yerel Yöntem)
Rafael Sanches

Saygılarımızla Rafael, Bunun orijinal sorunun Honeycomb'da çözülmüş olmasından kaynaklandığını düşünüyorum. Durumun bu olup olmadığını bilen var mı?
Scott

sadece onBackpress () veya geri düğmesine 2 satır koyun arka yığında geçmiş kalmaz, çok zaman kazandınız.
CrazyMind

36

Uygulamanızdan çıkış yaparken tüm web görünümü önbelleklerini temizlemek için:

CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookie();

Lollipop ve üstü için:

CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookies(ValueCallback);

1
hayatımı ve günümü kurtar.
Uday Nayak

2
Etkinliğinizde web görünümüne erişiminiz yoksa iyi çalışır. Ayrıca bu API'nin kullanımdan kaldırıldığını, bu nedenle L + cihazlarda bunun yerine "removeAllCookies (ValueCallback)" API'sini kullanın.
Akshat

ValueCallBack ile neyi değiştirmeliyim?
Qaisar Khan Bangash

@QaisarKhanBangash new ValueCallback <Boolean> () {atOverride public void onReceiveValue (Boolean değeri) {}}
amalBit

3

Bu, web görünümü önbelleğinizin olduğu yerde olması gereken uygulama önbelleğinizi temizlemelidir

File dir = getActivity().getCacheDir();

if (dir != null && dir.isDirectory()) {
    try {
        File[] children = dir.listFiles();
        if (children.length > 0) {
            for (int i = 0; i < children.length; i++) {
                File[] temp = children[i].listFiles();
                for (int x = 0; x < temp.length; x++) {
                    temp[x].delete();
                }
            }
        }
    } catch (Exception e) {
        Log.e("Cache", "failed cache clean");
    }
}

Bunu denedim (kod biraz değiştirildi) ve yine de aynı sonuçları aldım -> Yukarıda
açıklandı

3

Benim için çalışan tek çözüm

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
    CookieManager.getInstance().removeAllCookies(null);
    CookieManager.getInstance().flush();
} 

2

Sadece Kotlin'de aşağıdaki kodu kullanmak benim için çalışıyor

WebView(applicationContext).clearCache(true)

2

Çerez ve önbelleği Web görünümünden temizlemek için,

    // Clear all the Application Cache, Web SQL Database and the HTML5 Web Storage
    WebStorage.getInstance().deleteAllData();

    // Clear all the cookies
    CookieManager.getInstance().removeAllCookies(null);
    CookieManager.getInstance().flush();

    webView.clearCache(true);
    webView.clearFormData();
    webView.clearHistory();
    webView.clearSslPreferences();


0

Giriş alanlarına tıklandığında form verilerinin autopop olarak görüntülenmemesi için aşağıdaki yöntemi kullandığınızdan emin olun.

getSettings().setSaveFormData(false);

0
CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookie();

0
CookieSyncManager.createInstance(this);    
CookieManager cookieManager = CookieManager.getInstance(); 
cookieManager.removeAllCookie();

Google hesabımı web görünümümde temizleyebilir


2
CookieSyncManager kullanımdan kaldırıldı
Geliştirici

-1

kullanım durumu: öğe listesi geri dönüşümcü görünümünde görüntülenir, herhangi bir öğe tıklandığında geri dönüşümcü görünümünü gizler ve öğe url'si ile web görünümünü gösterir.

Sorun: i açtıktan sonra ben de benzer bir sorun var url_oneWeb görünümündeki içinde daha sonra başka açmaya, url_twogösterir, Web görünümündeki içinde url_onede arka kadar url_twoyüklenir.

çözüm: Yaptığım şeyi çözmek için, saklamadan ve yüklemeden hemen önce ""olduğu gibi boş bir dize yüklemek .urlurl_oneurl_two

çıktı: web görünümünde yeni bir url yüklediğimde arka planda başka bir web sayfası göstermiyor.

kod

public void showWebView(String url){
        webView.loadUrl(url);
        recyclerView.setVisibility(View.GONE);
        webView.setVisibility(View.VISIBLE);
    }

public void onListItemClick(String url){
   showWebView(url);
}

public void hideWebView(){
        // loading blank url so it overrides last open url
        webView.loadUrl("");
        webView.setVisibility(View.GONE);
        recyclerView.setVisibility(View.GONE);
   }


 @Override
public void onBackPressed() {
    if(webView.getVisibility() == View.VISIBLE){
        hideWebView();
    }else{
        super.onBackPressed();
    }
}

Bunun soruyla nasıl bir ilişkisi var?
Zun

@Zun aşağı oy verdiğiniz için teşekkürler ve geri bildirimi gerçekten takdir ediyorum ve sorunuza cevabım, benzer bir senaryoda sıkıştığım, ancak biraz farklı olduğum, ancak ikisinin de çıktıları aynı, bu yüzden cevabımı yazmadan önce Ayrıca bir kullanıcı vakası yazdım, bu, çerezleri kullanmadan, soruda sorulan benzer etkiyi elde edecek.
Abhishek Garg
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.