Android WebView 缓存

现在很多门户类信息网站,比如虎嗅,ifanr,钛媒体等等的 APP,简单点说是信息阅读类的 APP,但是在文章详情页面,还是直接嵌套一个 WebView 用来显示,这可能就涉及到了 WebView 的缓存了

页面缓存

页面缓存 就是指 WebView 第一次打开某个网页时会保存加载一个网页时所需的 HTML,JS,CSS 等页面相关的数据以及其它资源,当没网的时候或者 网络状态较差的时候,加载本地保存好的相关数据

几乎所有游览器都支持页面缓存功能,因为页面缓存能加快网页浏览速度,也能节省带宽和服务器资源

本章节我们就来学习如何设置 Android WebView 的缓存功能

缓存的分类

现代浏览器中的缓存,大致可以分为两大类:页面缓存和数据缓存

  1. 页面缓存

    加载一个网页时的 HTML、JS、CSS 等页面或者资源数据

    这些缓存资源是浏览器自身的行为而产生,开发者只能通过配置 HTTP 响应头影响浏览器的行为才能间接地影响到这些缓存数据

    Android Webview 页面缓存保存了两种数据

    1. 缓存的索引 放在

      /data/data/<包名>/cache/org.chromium.android_webkit/indexdir
      
    2. 缓存的文件 放在

      /data/data/<包名>/cache/org.chromium.android_webkit
      
  2. 数据缓存

    数据缓存又两种 AppCache 和 DOM Storage

    1. AppCache

      AppCache 时我们能够主动选择缓存 WEB 浏览器中所有的东西,从页面、图片到脚本、CSS 等等

      AppCache 数据保存在 ApplicationCache.db 中

      AppCache 需要调用方法 setAppCacheEnabled() 手动开启,同时要设置缓存保存的路径 setAppCachePath() 和容量 setAppCacheMaxSize()

      AppCache 目前支持 5M 的存储空间,所以使用时要谨慎,仅缓存最重要的东西

    2. DOM Storage

      存储一些简单的键值对(key/value) 数据

      根据作用范围的不同,分为 SessionStorage 和 Local Storage 两种,分别用于会话级别的存储(页面关闭即消失)和本地化存储(除非主动删除,否则数据永远不会过期

      DOMStorage 数据保存在

      /data/data/<包名>/app_webview/Local Storage/<filename>.localstorage
      

      Android 需要调用方法 setDomStorageEnabled() 手动开启 DOM Storage 并调用方法 setDatabasePath() 设置存储路径

WebView 缓存模式

模式 说明
LOAD_CACHE_ONLY 不使用网络,只读取本地缓存数据
LOAD_DEFAULT 根据cache-control决定是否从网络上取数据。
LOAD_CACHE_NORMAL已废弃 作用同 LOAD_DEFAULT 模式
LOAD_NO_CACHE 不使用缓存,只从网络获取数据
LOAD_CACHE_ELSE_NETWORK 只要本地有,无论是否过期,或者 no-cache,都使用缓存中的数据

开发中,我们建议缓存策略为

判断是否有网络,有的话,使用 LOAD_DEFAULT
无网络,使用 LOAD_CACHE_ELSE_NETWORK

删除 WebView 的缓存数据

如果要删除 WebView 的缓存数据,可以调用 clearCache( true ) 方法

当然了,WebView 还提供了大量的其它方法用于删除各种缓存

方法 说明
setting.setCacheMode(WebSettings.LOAD_NO_CACHE) 设置 WebView 不缓存,不缓存也就没缓存数据要删除了
deleteDatabase("WebView.db")
deleteDatabase("WebViewCache.db")
删除缓存的数据库
webView.clearHistory() 删除历史访问记录
webView.clearFormData() 删除自动表单数据
getCacheDir().delete() 删除缓存目录

WebView 开启缓存功能

操作过程如下

  1. 进入页面后默认加载 url,然后随便点击一个链接跳到第二个页面,退出 APP
  2. 开启飞行模式,关闭 wifi 以及移动网络,然后重新进入,发现无网络的情况下,页面还是加载了,打开第一个链接也可以加载,打开其它链接就发现找不到网页
  3. 点击清除缓存,把应用关闭,重新进入,发现页面已经打不开


  1. 创建一个 空的 Android 项目 cn.twle.android.WebViewCache

  2. 修改 AndroidManifest.xml 添加网络权限

    <uses-permission android:name="android.permission.INTERNET" />
    
  3. 修改 activity_main.xml 添加一个 WebView

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:padding="5dp"
        android:layout_width="match_parent"    
        android:layout_height="match_parent">
    
        <Button
            android:id="@+id/btn_refresh"
            android:layout_width="wrap_content"    
            android:layout_height="wrap_content"
            android:text="刷新" />
        <Button
            android:id="@+id/btn_clear"
            android:layout_width="wrap_content"    
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/btn_refresh" 
            android:text="清除缓存" />
    
        <WebView
            android:id="@+id/ms_webview"
            android:layout_width="match_parent" 
            android:layout_height="match_parent" />
    </RelativeLayout>
    
  4. 修改 MainActivity.java

    package cn.twle.android.webviewcache;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Button;
    
    import java.io.File;
    
    public class MainActivity extends AppCompatActivity {
    
        private WebView ms_webview;
        private Button btn_clear_cache;
        private Button btn_refresh;
    
        private static final String APP_CACHE_DIRNAME = "/webcache"; // web 缓存目录
        private static final String SITE_URL = "https://www.twle.cn/static/i/android/demo_a.html";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ms_webview = (WebView) findViewById(R.id.ms_webview);
            btn_refresh = (Button) findViewById(R.id.btn_refresh);
            btn_clear_cache = (Button) findViewById(R.id.btn_clear);
    
            ms_webview.loadUrl(SITE_URL);
    
            ms_webview.setWebViewClient(new WebViewClient() {
    
                //设置在 WebView 点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    view.loadUrl(url);
                    return true;
                }
            });
    
            WebSettings settings = ms_webview.getSettings();
    
            settings.setJavaScriptEnabled(true);
    
            //设置缓存模式
            settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    
            // 开启DOM storage API 功能
            settings.setDomStorageEnabled(true);
    
            // 开启database storage API功能
            settings.setDatabaseEnabled(true);
    
            String cacheDirPath = getCacheDir().getAbsolutePath() + APP_CACHE_DIRNAME;
    
            Log.d("webcache",cacheDirPath);
            File f = new File(cacheDirPath);
            if (!f.exists())
            {
                f.mkdirs();
            }
    
            // 设置数据库缓存路径
            settings.setAppCachePath(cacheDirPath);
            settings.setAppCacheEnabled(true);
    
            btn_clear_cache.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ms_webview.clearCache(true);
                }
            });
    
            btn_refresh.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    ms_webview.reload();
                }
            });
        }
    
        //  重写回退按钮的点击事件
        @Override
        public void onBackPressed() {
            if (ms_webview.canGoBack())
                ms_webview.goBack();
            else
                super.onBackPressed();
        }
    }
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

♥   简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.