Android Webview - Hapus Cache Sepenuhnya


111

Saya memiliki WebView di salah satu Aktivitas saya, dan saat memuat halaman web, halaman tersebut mengumpulkan beberapa data latar belakang dari Facebook.

Apa yang saya lihat, adalah halaman yang ditampilkan dalam aplikasi sama setiap kali aplikasi dibuka dan disegarkan.

Saya sudah mencoba mengatur WebView agar tidak menggunakan cache dan menghapus cache dan riwayat WebView.

Saya juga mengikuti saran di sini: Bagaimana cara mengosongkan cache untuk WebView?

Tetapi tidak ada yang berhasil, apakah ada yang punya ide tentang saya dapat mengatasi masalah ini karena ini adalah bagian penting dari aplikasi saya.

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

Jadi saya menerapkan saran pertama (Meskipun mengubah kode menjadi rekursif)

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

Namun ini masih belum mengubah apa yang ditampilkan halaman. Di browser desktop saya, saya mendapatkan kode html yang berbeda ke halaman web yang dihasilkan di WebView jadi saya tahu WebView harus di-cache di suatu tempat.

Pada saluran IRC saya diarahkan ke perbaikan untuk menghapus cache dari Koneksi URL tetapi belum dapat melihat bagaimana menerapkannya ke WebView.

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

Jika saya menghapus aplikasi saya dan menginstalnya kembali, saya bisa mendapatkan kembali halaman web tersebut, yaitu versi non-cache. Masalah utamanya adalah perubahan dilakukan pada tautan di halaman web, jadi bagian depan halaman web sama sekali tidak berubah.


1
mWebView.getSettings().setAppCacheEnabled(false);tidak berhasil?
Paul

Jawaban:


45

Potongan kode yang telah diedit di atas yang diposting oleh Gaunt Face berisi kesalahan bahwa jika direktori gagal dihapus karena salah satu filenya tidak dapat dihapus, kode akan terus mencoba kembali dalam putaran tak terbatas. Saya menulis ulang menjadi benar-benar rekursif, dan menambahkan parameter numDays sehingga Anda dapat mengontrol berapa lama file yang harus dipangkas:

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

Semoga bermanfaat bagi orang lain :)


Terima kasih banyak! kalian menyelamatkan hari saya :)
Kris

Rutinitas yang bagus, menyelamatkan kami dari banyak penderitaan.
Tn. Ed

Dapatkah saya menggunakan kode ini dalam aplikasi untuk menghapus cache untuk aplikasi tertentu yang diinstal di ponsel saya?
Si8

Jika seluruh direktori perlu dihapus tidak akan Runtime.getRuntime (). Exec ("rm -rf" + dirName + "\ n"); lebih mudah?
source.rar

@ source.rar Ya, tetapi Anda tidak memiliki kemampuan untuk menyimpan file yang lebih muda dari x hari, yang biasanya Anda inginkan untuk folder cache.
markjan

205

Saya menemukan solusi yang elegan dan sederhana untuk membersihkan cache

WebView obj;
obj.clearCache(true);

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

Saya telah mencoba mencari cara untuk menghapus cache, tetapi yang dapat kami lakukan dari metode yang disebutkan di atas hanyalah menghapus file lokal, tetapi tidak pernah membersihkan RAM.

API clearCache, membebaskan RAM yang digunakan oleh tampilan web dan karenanya mengamanatkan agar halaman web dimuat lagi.


11
Jawaban terbaik disini.
pengguna486134

Jawaban terbaik dan saya bertanya-tanya mengapa tidak diterima..Kudos Akshat :)
Karthik

1
Tidak beruntung bagiku. Ingin tahu apakah ada yang berubah? Saya dapat memuat WebView dengan google.com dan WebView masih menganggap saya masuk, bahkan setelah clearCache (true);
lostintranslation

2
@lostintranslation Untuk itu Anda mungkin ingin menghapus cookie. Meskipun saya yakin Anda sudah mengetahuinya sekarang.
NineToeNerd

Perlu mengalokasikan objek? Object WebView = new WebView (ini); obj.clearCache (true); Bagaimanapun, sangat bagus untuk saya, suara positif!
Giorgio Barchiesi

45

Saya menemukan perbaikan yang Anda cari:

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

Untuk beberapa alasan Android membuat cache url yang buruk yang terus muncul secara tidak sengaja alih-alih data baru yang Anda butuhkan. Tentu, Anda bisa saja menghapus entri dari DB tetapi dalam kasus saya, saya hanya mencoba mengakses satu URL sehingga membuang seluruh DB lebih mudah.

Dan jangan khawatir, DB ini hanya terkait dengan aplikasi Anda sehingga Anda tidak membersihkan cache dari seluruh ponsel.


Terima kasih, ini adalah trik yang sangat bagus. Itu pantas untuk dikenal lebih luas.
Philip Sheard

2
Ini memunculkan pengecualian buruk di honeycomb: 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): Gagal membuka database. menutupnya. 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): android.database.sqlite.SQLiteDiskIOException: kesalahan I / O disk 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): di android.database. sqlite.SQLiteDatabase.native_setLocale (Metode Asli)
Rafael Sanches

Salam Rafael, saya pikir ini karena masalah asli telah diselesaikan di Honeycomb. Adakah yang tahu jika ini masalahnya?
Scott

cukup letakkan 2 baris di onBackpress () atau tombol kembali tidak ada riwayat yang tersisa di back-stack terima kasih telah menghemat banyak waktu.
CrazyMind

36

Untuk menghapus semua cache tampilan web saat Anda signOUT dari APP Anda:

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

Untuk Lollipop ke atas:

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

1
selamatkan hidup dan hari saya.
Uday Nayak

2
Berfungsi dengan baik jika Anda tidak memiliki akses ke tampilan web dalam aktivitas Anda. Perhatikan juga bahwa API ini sudah tidak digunakan lagi, jadi gunakan API "removeAllCookies (ValueCallback)" sebagai gantinya di perangkat L +.
Akshat

apa yang harus saya ganti dengan ValueCallBack?
Qaisar Khan Bangash

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

3

Ini harus menghapus cache aplikasi Anda yang seharusnya berada di tempat cache tampilan web Anda berada

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

Mencoba ini (Kode diubah sedikit) dan masih mendapatkan hasil yang sama -> Dijelaskan di atas
Matt Gaunt

3

Satu-satunya solusi yang berhasil untuk saya

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

2

Cukup menggunakan kode di bawah ini di Kotlin bekerja untuk saya

WebView(applicationContext).clearCache(true)

2

Untuk menghapus cookie dan cache dari Webview,

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

Pastikan Anda menggunakan metode di bawah ini agar data formulir tidak ditampilkan sebagai autopop saat diklik pada bidang masukan.

getSettings().setSaveFormData(false);

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

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

Itu dapat menghapus akun google di tampilan web saya


2
CookieSyncManager dihapuskan
Pengembang

-1

use case: daftar item ditampilkan dalam tampilan recycler, setiap kali item diklik menyembunyikan tampilan recycler dan menampilkan tampilan web dengan url item.

Masalah: Saya memiliki masalah serupa di mana setelah saya membuka url_onedi webview, kemudian mencoba untuk membuka yang lain url_twodi webview, itu muncul url_onedi latar belakang sampai url_twodimuat.

solusi: jadi untuk mengatasi apa yang saya lakukan adalah memuat string kosong ""seperti urlsebelum bersembunyi url_onedan memuat url_two.

output: setiap kali saya memuat url baru di webview, itu tidak menampilkan halaman web lain di latar belakang.

kode

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

Bagaimana ini terkait dengan pertanyaan?
Zun

@Zun terima kasih untuk down voting, dan saya sangat menghargai umpan balik, dan jawaban saya untuk pertanyaan Anda adalah, bahwa saya terjebak dalam skenario yang sama, tetapi saya memiliki sedikit berbeda, tetapi output keduanya sama, jadi sebelum menulis jawaban saya Saya juga telah menulis kasus pengguna, itu akan mencapai efek yang sama seperti yang ditanyakan, tanpa perlu menangani cookie.
Abhishek Garg
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.