当我们加载Html时候,会在我们data/应用package下生成database与cache两个文件夹:
我们请求的Url记录是保存在webviewCache.db里,而url的内容是保存在webviewCache文件夹下.
WebView中存在着两种缓存:网页数据缓存(存储打开过的页面及资源)、H5缓存(即AppCache)。

一、网页缓存

1、缓存构成
/data/data/package_name/cache/
/data/data/package_name/database/webview.db

/data/data/package_name/database/webviewCache.db

WebView缓存文件结构如下图所示

再看一下 webviewCache 数据库结构

综合可以得知 webview 会将我们浏览过的网页url已经网页文件(css、图片、js等)保存到数据库表中

缓存模式(5种)
LOAD_CACHE_ONLY:  不使用网络,只读取本地缓存数据
LOAD_DEFAULT:  根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
如:www.taobao.com的cache-control为no-cache,在模式LOAD_DEFAULT下,无论如何都会从网络上取数据,如果没有网络,就会出现错误页面;在LOAD_CACHE_ELSE_NETWORK模式下,无论是否有网络,只要本地有缓存,都使用缓存。本地没有缓存时才从网络上获取。
www.360.com.cn的cache-control为max-age=60,在两种模式下都使用本地缓存数据。

总结:根据以上两种模式,建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK。

设置WebView 缓存模式

  1. private void initWebView() {
  2. mWebView.getSettings().setJavaScriptEnabled(true);
  3. mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);
  4. mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //设置 缓存模式
  5. // 开启 DOM storage API 功能
  6. mWebView.getSettings().setDomStorageEnabled(true);
  7. //开启 database storage API 功能
  8. mWebView.getSettings().setDatabaseEnabled(true);
  9. String cacheDirPath = getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME;
  10. //      String cacheDirPath = getCacheDir().getAbsolutePath()+Constant.APP_DB_DIRNAME;
  11. Log.i(TAG, "cacheDirPath="+cacheDirPath);
  12. //设置数据库缓存路径
  13. mWebView.getSettings().setDatabasePath(cacheDirPath);
  14. //设置  Application Caches 缓存目录
  15. mWebView.getSettings().setAppCachePath(cacheDirPath);
  16. //开启 Application Caches 功能
  17. mWebView.getSettings().setAppCacheEnabled(true);
  18. }

清除缓存

  1. /**
  2. * 清除WebView缓存
  3. */
  4. public void clearWebViewCache(){
  5. //清理Webview缓存数据库
  6. try {
  7. deleteDatabase("webview.db");
  8. deleteDatabase("webviewCache.db");
  9. } catch (Exception e) {
  10. e.printStackTrace();
  11. }
  12. //WebView 缓存文件
  13. File appCacheDir = new File(getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME);
  14. Log.e(TAG, "appCacheDir path="+appCacheDir.getAbsolutePath());
  15. File webviewCacheDir = new File(getCacheDir().getAbsolutePath()+"/webviewCache");
  16. Log.e(TAG, "webviewCacheDir path="+webviewCacheDir.getAbsolutePath());
  17. //删除webview 缓存目录
  18. if(webviewCacheDir.exists()){
  19. deleteFile(webviewCacheDir);
  20. }
  21. //删除webview 缓存 缓存目录
  22. if(appCacheDir.exists()){
  23. deleteFile(appCacheDir);
  24. }
  25. }

完整代码

  1. package com.example.webviewtest;
  2. import java.io.File;
  3. import android.app.Activity;
  4. import android.graphics.Bitmap;
  5. import android.os.Bundle;
  6. import android.util.Log;
  7. import android.view.View;
  8. import android.webkit.JsPromptResult;
  9. import android.webkit.JsResult;
  10. import android.webkit.WebChromeClient;
  11. import android.webkit.WebSettings;
  12. import android.webkit.WebSettings.RenderPriority;
  13. import android.webkit.WebView;
  14. import android.webkit.WebViewClient;
  15. import android.widget.RelativeLayout;
  16. import android.widget.TextView;
  17. import android.widget.Toast;
  18. public class MainActivity extends Activity {
  19. private static final String TAG = MainActivity.class.getSimpleName();
  20. private static final String APP_CACAHE_DIRNAME = "/webcache";
  21. private TextView tv_topbar_title;
  22. private RelativeLayout rl_loading;
  23. private WebView mWebView;
  24. private String url;
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29. //url:http://m.dianhua.cn/detail/31ccb426119d3c9eaa794df686c58636121d38bc?apikey=jFaWGVHdFVhekZYWTBWV1ZHSkZOVlJWY&app=com.yulore.yellowsdk_ios&uid=355136051337627
  30. url = "http://m.dianhua.cn/detail/31ccb426119d3c9eaa794df686c58636121d38bc?apikey=jFaWGVHdFVhekZYWTBWV1ZHSkZOVlJWY&app=com.yulore.yellowsdk_ios&uid=355136051337627";
  31. findView();
  32. }
  33. private void findView() {
  34. tv_topbar_title = (TextView) findViewById(R.id.tv_topbar_title);
  35. rl_loading = (RelativeLayout) findViewById(R.id.rl_loading);
  36. mWebView = (WebView) findViewById(R.id.mWebView);
  37. initWebView();
  38. mWebView.setWebViewClient(new WebViewClient() {
  39. @Override
  40. public void onLoadResource(WebView view, String url) {
  41. Log.i(TAG, "onLoadResource url="+url);
  42. super.onLoadResource(view, url);
  43. }
  44. @Override
  45. public boolean shouldOverrideUrlLoading(WebView webview, String url) {
  46. Log.i(TAG, "intercept url="+url);
  47. webview.loadUrl(url);
  48. return true;
  49. }
  50. @Override
  51. public void onPageStarted(WebView view, String url, Bitmap favicon) {
  52. Log.e(TAG, "onPageStarted");
  53. rl_loading.setVisibility(View.VISIBLE); // 显示加载界面
  54. }
  55. @Override
  56. public void onPageFinished(WebView view, String url) {
  57. String title = view.getTitle();
  58. Log.e(TAG, "onPageFinished WebView title=" + title);
  59. tv_topbar_title.setText(title);
  60. tv_topbar_title.setVisibility(View.VISIBLE);
  61. rl_loading.setVisibility(View.GONE); // 隐藏加载界面
  62. }
  63. @Override
  64. public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
  65. rl_loading.setVisibility(View.GONE); // 隐藏加载界面
  66. Toast.makeText(getApplicationContext(), "",
  67. Toast.LENGTH_LONG).show();
  68. }
  69. });
  70. mWebView.setWebChromeClient(new WebChromeClient() {
  71. @Override
  72. public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
  73. Log.e(TAG, "onJsAlert " + message);
  74. Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
  75. result.confirm();
  76. return true;
  77. }
  78. @Override
  79. public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
  80. Log.e(TAG, "onJsConfirm " + message);
  81. return super.onJsConfirm(view, url, message, result);
  82. }
  83. @Override
  84. public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
  85. Log.e(TAG, "onJsPrompt " + url);
  86. return super.onJsPrompt(view, url, message, defaultValue, result);
  87. }
  88. });
  89. mWebView.loadUrl(url);
  90. }
  91. private void initWebView() {
  92. mWebView.getSettings().setJavaScriptEnabled(true);
  93. mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);
  94. mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //设置 缓存模式
  95. // 开启 DOM storage API 功能
  96. mWebView.getSettings().setDomStorageEnabled(true);
  97. //开启 database storage API 功能
  98. mWebView.getSettings().setDatabaseEnabled(true);
  99. String cacheDirPath = getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME;
  100. //      String cacheDirPath = getCacheDir().getAbsolutePath()+Constant.APP_DB_DIRNAME;
  101. Log.i(TAG, "cacheDirPath="+cacheDirPath);
  102. //设置数据库缓存路径
  103. mWebView.getSettings().setDatabasePath(cacheDirPath);
  104. //设置  Application Caches 缓存目录
  105. mWebView.getSettings().setAppCachePath(cacheDirPath);
  106. //开启 Application Caches 功能
  107. mWebView.getSettings().setAppCacheEnabled(true);
  108. }
  109. /**
  110. * 清除WebView缓存
  111. */
  112. public void clearWebViewCache(){
  113. //清理Webview缓存数据库
  114. try {
  115. deleteDatabase("webview.db");
  116. deleteDatabase("webviewCache.db");
  117. } catch (Exception e) {
  118. e.printStackTrace();
  119. }
  120. //WebView 缓存文件
  121. File appCacheDir = new File(getFilesDir().getAbsolutePath()+APP_CACAHE_DIRNAME);
  122. Log.e(TAG, "appCacheDir path="+appCacheDir.getAbsolutePath());
  123. File webviewCacheDir = new File(getCacheDir().getAbsolutePath()+"/webviewCache");
  124. Log.e(TAG, "webviewCacheDir path="+webviewCacheDir.getAbsolutePath());
  125. //删除webview 缓存目录
  126. if(webviewCacheDir.exists()){
  127. deleteFile(webviewCacheDir);
  128. }
  129. //删除webview 缓存 缓存目录
  130. if(appCacheDir.exists()){
  131. deleteFile(appCacheDir);
  132. }
  133. }
  134. /**
  135. * 递归删除 文件/文件夹
  136. *
  137. * @param file
  138. */
  139. public void deleteFile(File file) {
  140. Log.i(TAG, "delete file path=" + file.getAbsolutePath());
  141. if (file.exists()) {
  142. if (file.isFile()) {
  143. file.delete();
  144. } else if (file.isDirectory()) {
  145. File files[] = file.listFiles();
  146. for (int i = 0; i < files.length; i++) {
  147. deleteFile(files[i]);
  148. }
  149. }
  150. file.delete();
  151. } else {
  152. Log.e(TAG, "delete file no exists " + file.getAbsolutePath());
  153. }
  154. }
  155. }

简洁版代码:

  1. System.out.println("getCacheDir: "+WebViewActivity.this.getCacheDir());
  2. System.out.println("PackageResourcePath(): "+WebViewActivity.this.getPackageCodePath());
  3. System.out.println("getCacheDir: "+WebViewActivity.this.getPackageResourcePath());
  4. System.out.println("FilesDir: "+WebViewActivity.this.getDatabasePath("webview.db").getPath());
  5. System.out.println("FilesDir: "+WebViewActivity.this.getFilesDir().getPath())
  1. 03-31 11:54:52.094: I/System.out(22224): getCacheDir: /data/data/com.liao.webview/cache
  2. 03-31 11:54:52.094: I/System.out(22224): PackageResourcePath(): /data/app/com.liao.webview-1.apk
  3. 03-31 11:54:52.115: I/System.out(22224): getCacheDir: /data/app/com.liao.webview-1.apk
  4. 03-31 11:54:52.115: I/System.out(22224): FilesDir: /data/data/com.liao.webview/databases/webview.db
  5. 03-31 11:54:52.154: I/System.out(22224): FilesDir: /data/data/com.liao.webview/files
  6. 03-31 11:54:52.265: I/ActivityManager(59): Displayed activity com.liao.webview/.WebViewActivity: 418 ms (total 418 ms)
  1. // clear the cache before time numDays
  2. private int clearCacheFolder(File dir, long numDays) {
  3. int deletedFiles = 0;
  4. if (dir!= null && dir.isDirectory()) {
  5. try {
  6. for (File child:dir.listFiles()) {
  7. if (child.isDirectory()) {
  8. deletedFiles += clearCacheFolder(child, numDays);
  9. }
  10. if (child.lastModified() < numDays) {
  11. if (child.delete()) {
  12. deletedFiles++;
  13. }
  14. }
  15. }
  16. } catch(Exception e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. return deletedFiles;
  21. }
  1. //优先使用缓存:
  2. WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
  1. <p>//不使用缓存:
  2. WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); </p>
  1. 退出的时候加上下面代码
  1. File file = CacheManager.getCacheFileBaseDir();
  2. if (file != null && file.exists() && file.isDirectory()) {
  3. for (File item : file.listFiles()) {
  4. item.delete();
  5. }
  6. file.delete();
  7. }
  8. context.deleteDatabase("webview.db");
  9. context.deleteDatabase("webviewCache.db");

WebView Cache 缓存清除的更多相关文章

  1. 王立平--WebView的缓存机制

    WebView的缓存能够分为页面缓存和数据缓存. 1.   页面缓存是指载入一个网页时的html.JS.CSS等页面或者资源数据. 这些缓存资源是因为浏览器的行为而产生.开发人员仅仅能通过配置HTTP ...

  2. Android WebView的缓存方式分析

    WebView的缓存可以分为(1)页面缓存和(2)数据缓存. 页面缓存是指当WebView加载一个网页时的html.JS.CSS等页面或者资源数据.这些缓存资源是由于浏览器的行为而产生,开发者只能通过 ...

  3. ms sql server缓存清除与内存释放

    Sql Server系统内 存管理在没有配置内存最大值,很多时候我们会发现运行Sql Server的系统内存往往居高不下.这是由于他对于内存使用的策略是有多少闲置的内存就占用多少,直到内存使用虑达到系 ...

  4. SQL Server 缓存清除与内存释放

    Sql Server系统内存管理在没有配置内存最大值,很多时候我们会发现运行SqlServer的系统内存往往居高不下.这是由于他对于内存使用的策略是有多少闲置的内存就占用多少,直到内存使用虑达到系统峰 ...

  5. Nginx 负载均衡的Cache缓存批量清理的操作记录

    1)nginx.conf配置 [root@inner-lb01 ~]# cat /data/nginx/conf/nginx.conf user www; worker_processes 8; #e ...

  6. SpringBoot日记——Cache缓存篇

    通常我们访问数据的情况如下图,数据存缓存就取缓存,不存缓存就取数据库,这样可以提升效率,不用一直读取数据库的信息: 开始记录: 关于SpringBoot缓存的应用 1. 首先在pom.xml文件中添加 ...

  7. springboot(九) Cache缓存和Redis缓存

    1. Cache缓存 1.1 缓存的概念&缓存注解 Cache 缓存接口,定义缓存操作.实现有:RedisCache.EhCacheCache.ConcurrentMapCache等 Cach ...

  8. ajax的cache缓存的使用方法

    ajax中cache缓存的使用: 问题描述: 在IE.360浏览器上提交表单后,保存后的内容不回显(依然显示空或者之前的内容). 原因: 回显内容是使用ajax的get方式的请求查询数据,ajax的c ...

  9. ASP.NET Core中使用Cache缓存

    ASP.NET Core中使用Cache缓存 缓存介绍: 通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性. 缓存对不经常更改的数据效果最佳. 缓存生成的数据副本的返回速度可以比从原始 ...

随机推荐

  1. java学习之反射机制

    java语言区别于C,C++等准静态语言的最大特点就是java的反射机制.静态语言的最直接定义就是不能在运行时改变程序结构或变量的类型.按照这样的定义,python,ruby是动态语言,C,C++,J ...

  2. 24种设计模式--桥梁模式【Bridge Pattern】

    今天我要说说我自己,梦想中的我自己,我身价过亿,有两个大公司,一个是房地产公司,一个是服装制造业,这两个公司都很赚钱,天天帮我在累加财富,其实是什么公司我倒是不关心,我关心的是是不是在赚钱,赚了多少, ...

  3. apache2.4配置虚拟目录

    刚开始学习,跟着韩顺平老师的视频课件学习ing~ 这是自己在配置虚拟目录时遇到的问题以及解决办法,记录下来~ ---------------------------分割线君-------------- ...

  4. 工欲善其事必先利其器-Notepad++使用小记(Python)

    大学开始就一直使用Notepad++ 作为代码编辑器,喜欢它的简洁明了,喜欢它的个性,也喜欢它各种各样骚气的插件. 今天闲来无事,写篇文章记录一下平时使用的种种,包括但不限于个性化使用一些宏,快捷键, ...

  5. WPF Navigation导航

    WPF导航这个话题,网上的解决方法有很多种,有点吃猪脚的感觉,弃之可惜,食之乏味. 不过还是简单聊聊吧. 常见的导航: 利用HyperLink导航,可以到某一个Page页面,也可以是外部链接,当然也可 ...

  6. 用typedef给结构体一个别名

    转:typedef 一.用typedef给结构体一个别名 typedef struct tagMyStruct { int iNum; long lLength; } MyStruct; 这语句实际上 ...

  7. 开启Eclipse 智能感知代码功能

    1.打开windows->Perferences..窗口,选择java->Editor->Content Assist,在右下方的“Auto Activation triggers  ...

  8. PYTHON文本处理指南之日志LOG解析

    处理特定字段的内容,并指指定条件输出. 注意代码中用一个方法列表,并且将方法参数延后传递. GOOGLE作过PYTHON代码的水平,就是不一样呀. 希望能学到这种通用的技巧. 只是,英文PDF看起来有 ...

  9. 【POJ2417】baby step giant step

    最近在学习数论,然而发现之前学的baby step giant step又忘了,于是去翻了翻以前的代码,又复习了一下. 觉得总是忘记是因为没有彻底理解啊. 注意baby step giant step ...

  10. 几个外国Delphi Blog网站

    http://blog.blong.com/search?updated-max=2012-09-19T03:21:00-07:00&max-results=7&start=42&am ...