WebView自动缓存-清除缓存

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebView自动缓存-清除缓存相关的知识,希望对你有一定的参考价值。

参考技术A ios的Webview加载html时会自动缓存JS、CSS等文件,当下次加载HTML时会根据请求的缓存策略是否使用缓存本地的JS和CSS,如果本地有缓存,那么直接返回本地资源(判断是否过期);如果没有本地缓存则向服务器请求地址。
1、NSURLRequestCachePolicy 指定缓存逻辑。URL加载系统提供了一个磁盘和内存混合的缓存,来响应网络请求。
2、NSURLRequestUseProtocolCachePolicy = 0 默认缓存策略
3、NSURLRequestReloadIgnoringLocalCacheData 不使用本地缓存数据
4、NSURLRequestReloadIgnoringLocalAndRemoteCacheData 直接加载源数据
5、NSURLRequestReturnCacheDataElseLoad 指定已存的缓存数据应该用来响应请求,不管它的生命时长和过期时间。
6、NSURLRequestReturnCacheDataDontLoad 指定已存的缓存数据用来满足请求,不管生命时长和过期时间。

也可以使用这个方法清除单个请求的缓存

之前遇到一种情况,app端加载服务器一个网页,js调用http接口没有传参数报错了,服务端更新之后安卓重新加载没有问题,iOS端一直加载都会报错,卸载重装之后就没问题了。
最后发现在沙盒的Caches目录中找到一个WebKit的文件夹,把这个文件夹删了也没问题

借鉴:
html开发变态的静态资源缓存与更新
iOS开发:解决UIWebView自动缓存导致页面不可刷新问题
iOS html5使用缓存并及时更新方案总结

Android Webview - 完全清除缓存

【中文标题】Android Webview - 完全清除缓存【英文标题】:Android Webview - Completely Clear the Cache 【发布时间】:2011-01-28 18:08:31 【问题描述】:

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

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

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

我也遵循了这里的建议:How to empty cache for 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");
        
    

但这仍然没有改变页面显示的内容。在我的桌面浏览器上,我得到了与 WebView 中生成的网页不同的 html 代码,所以我知道 WebView 必须在某处缓存。

在 IRC 频道上,有人向我指出了从 URL 连接中删除缓存的修复程序,但还看不到如何将其应用于 WebView。

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

如果我删除我的应用程序并重新安装它,我可以使网页恢复到最新状态,即非缓存版本。主要问题是网页中的链接发生了变化,所以网页的前端完全没有变化。

【问题讨论】:

mWebView.getSettings().setAppCacheEnabled(false); 没用? 【参考方案1】:

我找到了一个更优雅简单的清除缓存的解决方案

WebView obj;
obj.clearCache(true);

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

我一直在想办法清除缓存,但我们可以从上述方法中做的就是删除本地文件,但它永远不会清除 RAM。

API clearCache 释放了 webview 使用的 RAM,因此要求重新加载网页。

【讨论】:

最好的答案,我想知道为什么它不被接受..Kudos Akshat :) 我运气不好。想知道有什么改变吗?我可以使用 google.com 加载 WebView 并且 WebView 仍然认为我已登录,即使在 clearCache(true); @lostintranslation 为此,您可能想删除 cookie。虽然我相信你现在已经发现了。 需要分配对象吗? WebView obj = new WebView(this); obj.clearCache(true);无论如何,对我来说非常好,点赞!【参考方案2】:

我找到了您正在寻找的解决方法:

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

由于某种原因,Android 会错误地缓存 url,它会意外返回,而不是您需要的新数据。当然,您可以从数据库中删除条目,但在我的情况下,我只尝试访问一个 URL,因此更容易删除整个数据库。

不用担心,这些数据库只是与您的应用关联,因此您不会清除整个手机的缓存。

【讨论】:

谢谢,这是一个非常巧妙的技巧。它值得更广为人知。 这会在蜂窝中引发一个讨厌的异常: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(Native Method) 干杯拉斐尔,我想这是因为原始问题已在 Honeycomb 中解决。有人知道是不是这样吗? 只需将 2 行放在 onBackpress() 或后退按钮中,后退堆栈中不会保留任何历史记录,这节省了很多时间。【参考方案3】:

上面 Gaunt Face 发布的编辑后的代码 sn-p 包含一个错误,即如果一个目录因为其中一个文件无法删除而无法删除,代码将在无限循环中不断重试。我将其重写为真正的递归,并添加了一个 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));

希望对其他人有用:)

【讨论】:

非常感谢!你们拯救了我的一天:) 很棒的例程,为我们节省了很多痛苦。 我可以在应用程序中使用此代码来清除手机上安装的某些应用程序的缓存吗? 如果需要删除整个目录不会 Runtime.getRuntime().exec("rm -rf "+dirName+"\n");更容易吗? @source.rar 是的,但是您无法保留小于 x 天的文件,这通常需要缓存文件夹。【参考方案4】:

在您从 APP 注销时清除所有 webview 缓存:

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

棒棒糖及以上:

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

【讨论】:

拯救我的生命和一天。 如果您在活动中无权访问 webview,则可以正常工作。另请注意,此 API 已被弃用,因此请在 L+ 设备上使用“removeAllCookies(ValueCallback)”API。 我应该用 ValueCallBack 替换什么? @QaisarKhanBangash new ValueCallback() atOverride public void onReceiveValue(Boolean value) 【参考方案5】:

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

【讨论】:

【参考方案6】:

唯一适合我的解决方案

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

【讨论】:

【参考方案7】:

这应该清除您的应用程序缓存,这应该是您的 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");
    

【讨论】:

试过这个(稍微改变了代码),仍然得到相同的结果 -> 上面解释了【参考方案8】:
webView.clearCache(true)
appFormWebView.clearFormData()
appFormWebView.clearHistory()
appFormWebView.clearSslPreferences()
CookieManager.getInstance().removeAllCookies(null)
CookieManager.getInstance().flush()
WebStorage.getInstance().deleteAllData()

【讨论】:

【参考方案9】:

只需在 Kotlin 中使用以下代码即可为我工作

WebView(applicationContext).clearCache(true)

【讨论】:

【参考方案10】:

要清除历史记录,只需执行以下操作:

this.appView.clearHistory();

来源:http://developer.android.com/reference/android/webkit/WebView.html

【讨论】:

【参考方案11】:

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

getSettings().setSaveFormData(false);

【讨论】:

【参考方案12】:
CookieSyncManager.createInstance(this);         
CookieManager cookieManager = CookieManager.getInstance();        
cookieManager.removeAllCookie();

【讨论】:

【参考方案13】:
CookieSyncManager.createInstance(this);    
CookieManager cookieManager = CookieManager.getInstance(); 
cookieManager.removeAllCookie();

它可以在我的网页视图中清除谷歌帐户

【讨论】:

CookieSyncManager 已弃用【参考方案14】:
context.deleteDatabase("webview.db");
context.deleteDatabase("webviewCache.db")

成功了

【讨论】:

【参考方案15】:

要彻底清除 kotlin 中的缓存,您可以使用:

context.cacheDir.deleteRecursively()

以防万一有人需要 kotlin 代码 (:

【讨论】:

以上是关于WebView自动缓存-清除缓存的主要内容,如果未能解决你的问题,请参考以下文章

android开发,用webview打开本地html网页时,怎么清除缓存

android 清除缓存功能

iOS - 在 WebView 中清除返回缓存

Swift 在应用程序终止时清除 webview 缓存

iOS web缓存策略以及手动清除缓存

清除 UIWebview 缓存