Android Webview-完全清除缓存


111

我的一个活动中有一个WebView,加载网页时,该页面从Facebook收集一些背景数据。

我所看到的是,每次打开和刷新应用程序时,应用程序中显示的页面都是相同的。

我尝试将WebView设置为不使用缓存,并清除WebView的缓存和历史记录。

我在这里也遵循了建议:如何为WebView清空缓存?

但是这些都不起作用,没有人有任何想法可以克服这个问题,因为它是我应用程序的重要组成部分。

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

因此,我实现了第一个建议(尽管将代码更改为递归的)

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

但是,这仍然没有更改页面显示的内容。在桌面浏览器上,我得到的HTML代码与WebView中生成的网页不同,因此我知道WebView必须缓存在某个地方。

在IRC频道上,我被指出了一个修复程序,用于从URL连接中删除缓存,但是目前还看不到如何将其应用于WebView。

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

如果删除我的应用程序并重新安装,我可以使网页恢复最新状态,即非缓存版本。主要问题是对网页中的链接进行了更改,因此网页的前端完全不变。


1
mWebView.getSettings().setAppCacheEnabled(false);没有工作?
保罗

Answers:


45

Gaunt Face发布的上述经过编辑的代码段包含一个错误,即如果由于无法删除其文件之一而无法删除目录,则该代码将无限循环地重试。我将其重写为真正的递归,并添加了numDays参数,以便您可以控制修剪的文件必须多大:

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

希望对其他人有用:)


非常感谢!你们拯救了我的一天:)
克里斯(Kris)

例行公事,为我们节省了很多痛苦。
埃德先生

我可以在应用程序内使用此代码来清除手机上安装的某些应用程序的缓存吗?
2013年

如果整个目录都需要删除,则不会运行Runtime.getRuntime()。exec(“ rm -rf” + dirName +“ \ n”); 容易些吗?
source.rar 2014年

@ source.rar是的,但是您不能保留小于x天的文件,而这通常是您想要的缓存文件夹。
markjan 2014年

205

我找到了一种清除缓存的更简便的解决方案

WebView obj;
obj.clearCache(true);

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

我一直试图找出清除缓存的方法,但是从上述方法中我们所能做的就是删除本地文件,但它从未清理RAM。

API clearCache释放了Web视图使用的RAM,因此要求再次加载该页面。


11
最好的答案在这里。
user486134 2013年

最好的答案,我想知道为什么它不被接受..Kudos Akshat :)
Karthik

1
我没有运气。想知道是否有所改变?我可以使用google.com加载WebView,并且即使在clearCache(true)之后,WebView仍认为我已登录;
lostintranslation 2015年

2
@lostintranslation为此,您可能要删除cookie。虽然我确定您现在已经发现了。
NineToeNerd '16

需要分配对象吗?WebView obj =新的WebView(this); obj.clearCache(true); 无论如何,对我很好,赞成!
Giorgio Barchiesi

45

我找到了您要查找的修复程序:

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

出于某种原因,Android对URL进行了错误的缓存,使其意外返回,而不是您需要的新数据。当然,您可以仅从数据库中删除条目,但就我而言,我仅尝试访问一个URL,因此删除整个数据库更加容易。

不用担心,这些数据库仅与您的应用程序关联,因此您无需清除整个手机的缓存。


谢谢,这是一个非常巧妙的技巧。它应该得到更广泛的了解。
菲利普·谢德

2
这会在蜂窝中引发一个令人讨厌的异常:06-14 22:33:34.349:ERROR / SQLiteDatabase(20382):无法打开数据库。关闭它。06-14 22:33:34.349:ERROR / SQLiteDatabase(20382):android.database.sqlite.SQLiteDiskIOException:磁盘I / O错误06-14 22:33:34.349:ERROR / SQLiteDatabase(20382):位于android.database。 sqlite.SQLiteDatabase.native_setLocale(本机方法)
拉斐尔·桑切斯

干杯Rafael,我想这是因为原始问题已在Honeycomb中解决。有谁知道是这样吗?
斯科特,

只需在onBackpress()或后退按钮中放两行,由于节省了很多时间,历史记录不会保留在后退堆栈中。
CrazyMind

36

要在退出APP时清除所有Web视图缓存,请执行以下操作:

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

对于棒棒糖及以上:

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

1
拯救我的生命和一天。
Uday Nayak

2
如果您在活动中无权访问Webview,则效果很好。另请注意,此API已被弃用,因此请在L +设备上使用“ removeAllCookies(ValueCallback)” API。
Akshat'2

我应该用ValueCallBack替换什么?
Qaisar Khan Bangash

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

3

这应清除您的应用程序缓存,该缓存应位于您的Webview缓存所在的位置

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

尝试了一下(略微更改了代码),仍然得到了相同的结果->以上解释
Matt Gaunt 2010年

3

唯一适合我的解决方案

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

2

只需在Kotlin中使用以下代码即可

WebView(applicationContext).clearCache(true)

2

要从Webview清除Cookie和缓存,

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

确保使用以下方法,以确保在单击输入字段时表单数据不会显示为自动弹出。

getSettings().setSaveFormData(false);

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

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

它可以清除我的网络视图中的Google帐户


2
CookieSyncManager简述
开发人员

-1

用例:项目列表在回收器视图中显示,每当单击任何项​​目时,它都会隐藏回收器视图并显示带有项目URL的Web视图。

问题: 我也有类似的问题,一旦我url_one在webview中打开一个,然后尝试url_two在webview中打开另一个,它会url_one后台显示直到url_two加载。

解决方案: 可以这么解决我所做的是负载空字符串""作为url只是隐藏之前url_one和加载url_two

输出:每当我在webview中加载任何新网址时,它都不会在后台显示任何其他网页。

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

这与问题有什么关系?
Zun

@Zun感谢投反对票,我非常感谢您的反馈,我对您的问题的回答是,我陷入了类似的情况,但是我并没有什么不同,但是两者的输出都是相同的,因此在写我的答案之前我还编写了一个用户案例,它将实现与所问问题类似的效果,而无需处理Cookie。
Abhishek Garg,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.