Android Webview - Xóa hoàn toàn bộ nhớ cache


111

Tôi có một WebView trong một trong các Hoạt động của mình và khi nó tải một trang web, trang đó sẽ thu thập một số dữ liệu nền từ Facebook.

Những gì tôi đang thấy là trang được hiển thị trong ứng dụng giống nhau vào mỗi lần ứng dụng được mở và làm mới.

Tôi đã thử đặt WebView không sử dụng bộ nhớ cache và xóa bộ nhớ cache và lịch sử của WebView.

Tôi cũng đã làm theo gợi ý ở đây: Làm cách nào để xóa bộ nhớ cache cho WebView?

Nhưng không ai trong số này hoạt động, có ai có bất kỳ ý tưởng nào về việc tôi có thể khắc phục vấn đề này vì nó là một phần quan trọng trong ứng dụng của tôi.

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

Vì vậy, tôi đã triển khai đề xuất đầu tiên (Mặc dù đã thay đổi mã thành đệ quy)

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

Tuy nhiên, điều này vẫn không thay đổi những gì trang đang hiển thị. Trên trình duyệt máy tính để bàn của mình, tôi nhận được mã html khác nhau cho trang web được tạo trong WebView, vì vậy tôi biết WebView phải được lưu vào bộ nhớ đệm ở đâu đó.

Trên kênh IRC, tôi đã được chỉ ra một bản sửa lỗi để xóa bộ nhớ đệm khỏi Kết nối URL nhưng chưa thể biết cách áp dụng nó cho WebView.

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

Nếu tôi xóa ứng dụng của mình và cài đặt lại, tôi có thể cập nhật lại trang web, tức là phiên bản không được lưu trong bộ nhớ cache. Vấn đề chính là những thay đổi được thực hiện đối với các liên kết trong trang web, vì vậy giao diện người dùng của trang web hoàn toàn không thay đổi.


1
mWebView.getSettings().setAppCacheEnabled(false);đã không hoạt động?
Paul

Câu trả lời:


45

Đoạn mã đã chỉnh sửa ở trên được đăng bởi Gaunt Face có một lỗi trong đó nếu một thư mục không xóa được vì không thể xóa một trong các tệp của nó, thì mã sẽ tiếp tục thử lại trong một vòng lặp vô hạn. Tôi đã viết lại nó để thực sự là đệ quy và thêm một tham số numDays để bạn có thể kiểm soát mức độ cũ của các tệp đã được lược bớt:

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

Hy vọng sử dụng cho những người khác :)


Cảm ơn rất nhiều! các bạn đã cứu ngày của tôi :)
Kris

Thông lệ tuyệt vời, đã cứu chúng ta rất nhiều đau đớn.
Mr Ed

Tôi có thể sử dụng mã này trong một ứng dụng để xóa bộ nhớ cache cho một số ứng dụng được cài đặt trên điện thoại của tôi không?
Si8

Nếu toàn bộ thư mục cần được xóa sẽ không Runtime.getRuntime (). Execute ("rm -rf" + dirName + "\ n"); dễ dàng hơn?
source.rar Ngày

@ source.rar Có, nhưng sau đó bạn không có khả năng giữ các tệp nhỏ hơn x ngày tuổi, mà thông thường bạn muốn cho một thư mục bộ nhớ cache.
markjan

205

Tôi đã tìm thấy một giải pháp đơn giản và thanh lịch để xóa bộ nhớ cache

WebView obj;
obj.clearCache(true);

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

Tôi đã cố gắng tìm ra cách để xóa bộ nhớ cache, nhưng tất cả những gì chúng tôi có thể làm từ các phương pháp được đề cập ở trên là xóa các tệp cục bộ, nhưng nó không bao giờ làm sạch RAM.

API clearCache, giải phóng RAM được sử dụng bởi webview và do đó yêu cầu tải lại trang web.


11
Câu trả lời tốt nhất ở đây.
user486134

Câu trả lời tốt nhất và tôi tự hỏi tại sao không nó accepted..Kudos Akshat :)
Karthik

1
Không có may mắn cho tôi. Tự hỏi nếu điều gì đó đã thay đổi? Tôi có thể tải một WebView bằng google.com và WebView vẫn cho rằng tôi đã đăng nhập, ngay cả sau khi clearCache (true);
lostintranslation

2
@lostintranslation Vì điều đó có thể bạn muốn xóa cookie. Mặc dù tôi chắc rằng bây giờ bạn đã tìm ra điều đó.
NineToeNerd

Cần phân bổ đối tượng? WebView obj = new WebView (this); obj.clearCache (true); Dù sao, rất tốt cho tôi, đã ủng hộ!
Giorgio Barchiesi

45

Tôi đã tìm thấy bản sửa lỗi mà bạn đang tìm kiếm:

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

Vì một số lý do, Android tạo ra một bộ nhớ cache xấu của url mà nó liên tục quay trở lại một cách tình cờ thay vì dữ liệu mới mà bạn cần. Chắc chắn, bạn có thể xóa các mục nhập khỏi DB nhưng trong trường hợp của tôi, tôi chỉ cố gắng truy cập một URL để xóa toàn bộ DB dễ dàng hơn.

Và đừng lo lắng, các DB này chỉ được liên kết với ứng dụng của bạn nên bạn không xóa bộ nhớ cache của toàn bộ điện thoại.


Cảm ơn, đây là một thủ thuật cực kỳ gọn gàng. Nó xứng đáng được biết đến rộng rãi hơn.
Philip Sheard

2
Điều này ném ra một ngoại lệ khó chịu trong honeycomb: 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): Không mở được cơ sở dữ liệu. đóng nó lại. 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): android.database.sqlite.SQLiteDiskIOException: lỗi I / O đĩa 06-14 22: 33: 34.349: ERROR / SQLiteDatabase (20382): tại android.database. sqlite.SQLiteDatabase.native_setLocale (Native Method)
Rafael Sanches

Chúc mừng Rafael, tôi muốn nghĩ điều này là do vấn đề ban đầu đã được giải quyết trong Honeycomb. Có ai biết nếu điều này là trường hợp?
Scott

chỉ cần đặt 2 dòng vào onBackpress () hoặc nút quay lại mà không có lịch sử nào ở lại ngăn xếp nhờ tiết kiệm rất nhiều thời gian.
CrazyMind 21/12/16

36

Để xóa tất cả các bộ nhớ đệm của chế độ xem web trong khi bạn đăng nhập vào biểu mẫu ứng dụng của bạn:

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

Đối với Lollipop trở lên:

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

1
cứu cuộc sống của tôi và ngày.
Uday Nayak

2
Hoạt động tốt nếu bạn không có quyền truy cập vào webview trong hoạt động của mình. Cũng xin lưu ý rằng API này không được dùng nữa, vì vậy hãy sử dụng API "removeAllCookies (ValueCallback)" thay thế trên các thiết bị L +.
Akshat

tôi nên thay thế gì bằng ValueCallBack?
Qaisar Khan Bangash

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

3

Thao tác này sẽ xóa bộ nhớ cache ứng dụng của bạn, đây sẽ là nơi chứa bộ nhớ cache của chế độ xem web của bạn

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

Cố gắng này (Thay đổi mã hơi) và vẫn nhận được kết quả tương tự -> Giải thích trên
Matt Gaunt

3

Giải pháp duy nhất phù hợp với tôi

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

2

Đơn giản chỉ cần sử dụng mã dưới đây trong Kotlin phù hợp với tôi

WebView(applicationContext).clearCache(true)

2

Để xóa cookie và bộ nhớ cache khỏi 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

Đảm bảo rằng bạn sử dụng phương pháp dưới đây để dữ liệu biểu mẫu không được hiển thị dưới dạng tự động mở khi nhấp vào các trường nhập.

getSettings().setSaveFormData(false);

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

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

Nó có thể xóa tài khoản google trong webview của tôi


2
CookieSyncManager bị mô tả
Nhà phát triển

-1

ca sử dụng: danh sách mặt hàng đang hiển thị trong chế độ xem người tái chế, bất cứ khi nào có bất kỳ mục nào nhấp vào, nó sẽ ẩn chế độ xem người tái chế và hiển thị chế độ xem web với url mặt hàng.

sự cố: tôi gặp sự cố tương tự, trong đó khi tôi mở một url_onetrong chế độ xem web, sau đó cố gắng mở một url_twochế độ xem khác trong chế độ xem web, nó sẽ hiển thị url_onetrong nền cho đến khi url_twođược tải.

giải pháp: vì vậy để giải quyết những gì tôi đã làm là tải chuỗi trống ""như urlngay trước khi ẩn url_onevà tải url_two.

đầu ra: bất cứ khi nào tôi tải bất kỳ url mới nào trong chế độ xem web, nó không hiển thị bất kỳ trang web nào khác trong nền.

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

Điều này liên quan đến câu hỏi như thế nào?
Zun

@Zun cảm ơn bạn đã bỏ phiếu xuống và tôi thực sự đánh giá cao phản hồi và câu trả lời của tôi cho câu hỏi của bạn là, tôi đang mắc kẹt trong tình huống tương tự, nhưng tôi có một chút khác biệt, nhưng kết quả của cả hai đều giống nhau, vì vậy trước khi viết câu trả lời của tôi Tôi cũng đã viết một trường hợp người dùng, nó sẽ đạt được hiệu quả tương tự như được hỏi trong câu hỏi, mà không cần phải xử lý cookie.
Abhishek Garg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.