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. 数据缓存

    数据缓存又两种 AppCacheDOM Storage

    1. AppCache

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

      AppCache 数据保存在 ApplicationCache.db

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

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

    2. DOM Storage

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

      根据作用范围的不同,分为 SessionStorageLocal 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.