【Android面试题】高级UI面试题—— WebView如何做
WebView如何做资源缓存?
这道题想考察什么?
- 是否了解WebView如何做资源缓存操作与真实场景使用,是否熟悉WebView如何做资源缓存
考察的知识点
- WebView如何做资源缓存的概念在项目中使用与基本知识
考生应该如何回答
一般H5的加载流程:
- 加载开始前做初始化工作,包括Runtime初始化,创建WebView等;
- 完成初始化之后,WebView开始去请求资源加载H5页面;
- 页面发起CGI请求对应的数据(或者通过本地缓存获取),拿到数据后对DOM进行操作更新。
从流程上看存在的直观的问题:
- 终端耗时:终端初始化阶段的时间里(网络资料显示耗时在1s以上),网络完全是处于空闲等待状态的,浪费时间;
- 资源和数据动态拉取,获取的速度受制于网络速度;
那么解决方案是怎样的呢?
针对上述问题,主流的解决方案有:
- WebView自带的H5缓存机制
- 预加载
- 离线包
下面我们就重点分析一下缓存机制的解决方案。
1.缓存机制
H5中有很多的特性,其中就包括离线存储(也可称为缓存机制)这个重要的特性。加入了缓存机制,意味着web应用可以进行缓存,在没有网络的情况下进行离线访问。缓存机制带来的好处包括:
- 离线访问:用户可以在离线环境下使用
- 提高速度:缓存在本地的资源加载速度更快
- 减少服务器压力:只需下载更新过的文件,无需每次加载页面都进行一次完整的请求流程
到目前为止,H5的缓存机制一共有六种,分别是:
- 浏览器缓存机制
- Application Cache(AppCache)机制
- Dom Storgage(Web Storage)存储机制
- Web SQL Database存储机制
- Indexed Database(IndexedDB)
- File System API
下面我们详细分析一下这几种缓存机制
-
浏览器缓存机制
a. 原理
根据 HTTP 协议头里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段来控制文件缓存的机制
下面详细介绍Cache-Control、Expires、Last-Modified & Etag四个字段Cache-Control:用于控制文件在本地缓存有效时长。
如服务器回包:Cache-Control:max-age=600,则表示文件在本地应该缓存,且有效时长是600秒(从发出请求算起)。在接下来600秒内,如果有请求这个资源,浏览器不会发出 HTTP 请求,而是直接使用本地缓存的文件。Expires:与Cache-Control功能相同,即控制缓存的有效时间。
- Expires是 HTTP1.0 标准中的字段,Cache-Control 是 HTTP1.1 标准中新加的字段
- 当这两个字段同时出现时,Cache-Control 优先级较高
Last-Modified:标识文件在服务器上的最新更新时间。
下次请求时,如果文件缓存过期,浏览器通过 If-Modified-Since 字段带上这个时间,发送给服务器,由服务器比较时间戳来判断文件是否有修改。如果没有修改,服务器返回304告诉浏览器继续使用缓存;如果有修改,则返回200,同时返回最新的文件。
Etag:功能同Last-Modified ,即标识文件在服务器上的最新更新时间。
1.不同的是,Etag 的取值是一个对文件进行标识的特征字串。
2.在向服务器查询文件是否有更新时,浏览器通过If-None-Match 字段把特征字串发送给服务器,由服务器和文件最新特征字串进行匹配,来判断文件是否有更新:没有更新回包304,有更新回包200
3.Etag 和 Last-Modified 可根据需求使用一个或两个同时使用。两个同时使用时,只要满足基中一个条件,就认为文件没有更新。
常见用法是:
- Cache-Control与 Last-Modified一起使用;
- Expires与 Etag一起使用;
即一个用于控制缓存有效时间,一个用于在缓存失效后,向服务查询是否有更新
特别注意:浏览器缓存机制 是 浏览器内核的机制,一般都是标准的实现
即Cache-Control、 Last-Modified 、 Expires、 Etag都是标准实现,你不需要操心
b. 特点
- 优点:支持 Http协议层
- 不足:缓存文件需要首次加载后才会产生;浏览器缓存的存储空间有限,缓存有被清除的可能;缓存的文件没有校验。
对于解决以上问题,可以参考手 Q 的离线包
c. 应用场景
静态资源文件的存储,如JS、CSS、字体、图片等。Android Webview会将缓存的文件记录及文件内容会存在当前 app 的 data 目录中。WebView内置自动实现,使用默认的CacheMode就可以实现。
2. Application Cache 缓存机制
a. 原理
- 以文件为单位进行缓存,且文件有一定更新机制(类似于浏览器缓存机制)
- AppCache 原理有两个关键点:manifest 属性和 manifest 文件。
<!DOCTYPE html>
<html manifest="demo_html.appcache">
// HTML 在头中通过 manifest 属性引用 manifest 文件
// manifest 文件:就是上面以 appcache 结尾的文件,是一个普通文件文件,列出了需要缓存的文件
// 浏览器在首次加载 HTML 文件时,会解析 manifest 属性,并读取 manifest 文件,获取 Section:CACHE MANIFEST 下要缓存的文件列表,再对文件缓存
<body>
...
</body>
</html>
原理说明如下:
AppCache 在首次加载生成后,也有更新机制。被缓存的文件如果要更新,需要更新 manifest 文件。 因为浏览器在下次加载时,除了会默认使用缓存外,还会在后台检查 manifest 文件有没有修改(byte by byte)发现有修改,就会重新获取 manifest 文件,对 Section:CACHE MANIFEST 下文件列表检查更新manifest 文件与缓存文件的检查更新也遵守浏览器缓存机制,如用户手动清了 AppCache 缓存,下次加载时,浏览器会重新生成缓存,也可算是一种缓存的更新。AppCache 的缓存文件,与浏览器的缓存文件分开存储的,因为 AppCache 在本地有 5MB(分 HOST)的空间限制
b. 特点
方便构建Web App的缓存,专门为 Web App离线使用而开发的缓存机制.
c. 应用场景
存储静态文件(如JS、CSS、字体文件)
- 应用场景 同 浏览器缓存机制
- 但AppCache 是对 浏览器缓存机制 的补充,不是替代。
d. 具体实现
// 通过设置WebView的settings来实现
WebSettings settings = getSettings();
String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
settings.setAppCachePath(cacheDirPath);
// 1. 设置缓存路径
settings.setAppCacheMaxSize(20*1024*1024);
// 2. 设置缓存大小
settings.setAppCacheEnabled(true);
// 3. 开启Application Cache存储机制
// 特别注意
// 每个 Application 只调用一次 WebSettings.setAppCachePath() 和
WebSettings.setAppCacheMaxSize()
3.Dom Storage存储机制
Dom Storage的官方描述为:DOM 存储是一套在 Web Applications 1.0 规范中首次引入的与存储相关的特性的总称,现在已经分离出来,单独发展成为独立的 W3C Web 存储规范。 DOM存储被设计为用来提供一个更大存储量、更安全、更便捷的存储方法,从而可以代替掉将一些不需要让服务器知道的信息存储到 cookies里的这种传统方法。 Dom Storage机制类似Cookies,但有一些优势。Dom Storage是通过存储字符串的Key-Value对来提供的, Dom Storage存储的数据在本地,不像Cookies,每次请求一次页面,Cookies都会发送给服务器。 DOM Storage分为sessionStorage和localStorage,二者使用方法基本相同,区别在于作用范围不同:前者具有临时性,用来存储与页面相关的数据,它在页面关闭后无法使用,后者具备持久性,即保存的数据在页面关闭后也可以使用。
- sessionStorage 是个全局对象,它维护着在页面会话(page session)期间有效的存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。
- localStorage保存的数据是持久性的。当前PAGE关闭(Page Session结束后),保存的数据依然存在。重新打开PAGE,上次保存的数据可以获取到。另外,Local Storage 是全局性的,同时打开两个 PAGE 会共享一份存数据,在一个PAGE中修改数据,另一个 PAGE 中是可以感知到的。
Dom Storage的优势在于:存储空间(5M)大,远远大于Cookies(4KB),而且数据存储在本地无需经常和服务器进行交互,存储安全、便捷。可用于存储临时的简单数据。作用机制类似于SharedPreference
。但是,如果要存储结构化的数据,可能要借助JSON了,将要存储的对象转为JSON 串。不太适合存储比较复杂或存储空间要求比较大的数据,也不适合存储静态的文件。 使用方法如下:
webSettings.setDomStorageEnabled(true);
4. Web SQL Database存储机制
Web SQL Database基于SQL的数据库存储机制,用于存储适合数据库的结构化数据,充分利用数据库的优势,存储适合数据库的结构化数据,Web SQL Database存储机制提供了一组可方便对数据进行增加、删除、修改、查询。 Android系统也使用了大量的数据库用来存储数据,比如联系人、短消息等;数据库的格式为SQLite。Android也提供了API来操作SQLite。Web SQL Database存储机制就是通过提供一组API,借助浏览器的实现,将这种Native的功能提供给了Web。 实现方法为:
String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
// 设置缓存路径
webSettings.setDatabasePath(cacheDirPath);
webSettings.setDatabaseEnabled(true);
Web SQL Database存储机制官方已不再推荐使用,也已经停止了维护,取而代之的是IndexedDB缓存机制
5. Indexed Database(IndexedDB)
IndexedDB也是一种数据库的存储机制,但不同于已经不再支持 Web SQL Database缓存机制。IndexedDB不是传统的关系数据库,而是属于NoSQL数据库,通过存储字符串的Key-Value对来提供存储(类似于Dom Storage,但功能更强大,且存储空间更大)。其中Key是必需的,且唯一的,Key可以自己定义,也可由系统自动生成。Value也是必需的,但Value非常灵活,可以是任何类型的对象。一般Value通过Key来存取的。 IndexedDB提供了一组异步的API,可以进行数据存、取以及遍历。IndexedDB有个非常强大的功能:index(索引),它可对Value对象中任何属性生成索引,然后可以基于索引进行Value对象的快速查询。 IndexedDB集合了Dom Storage和Web SQL Database的优点,用于存储大块或复杂结构的数据,提供更大的存储空间,使用起来也比较简单。可以作为 Web SQL Database的替代。但是不太适合静态文件的缓存。 Android在4.4开始支持IndexedDB,开启方法如下:
webSettings.setJavaScriptEnabled(true);
6. File System
File System是H5新加入的存储机制。它为Web App提供了一个运行在沙盒中的虚拟的文件系统。不同WebApp的虚拟文件系统是互相隔离的,虚拟文件系统与本地文件系统也是互相隔离的。Web App在虚拟的文件系统中,通过File System API提供的一组文件与文件夹的操作接口进行文件(夹)的创建、读、写、删除、遍历等操作。 浏览器给虚拟文件系统提供了两种类型的存储空间:临时的和持久性的:
- 临时的存储空间是由浏览器自动分配的,但可能被浏览器回收;
- 持久性的存储空间需要显示的申请,申请时浏览器会给用户一提示,需要用户进行确认。持久性的存储空间是 WebApp 自己管理,浏览器不会回收,也不会清除内容。存储空间大小通过配额管理,首次申请时会一个初始的配额,配额用完需要再次申请。
File System的优势在于:
- 可存储数据体积较大的二进制数据
- 可预加载资源文件
- 可直接编辑文件
遗憾的是:由于File System是H5新加入的缓存机制,目前Android WebView暂时还不支持。
总结
缓存机制汇总
名称 | 原理 | 优点 | 适用对象 | 说明 |
---|---|---|---|---|
浏览器缓存 | 使用HTTP协议头部字段进行缓存控制 | 支持HTTP协议层 | 存储静态资源 | Android默认实现 |
Dom Storage | 通过存储键值对实现 | 存储空间大,数据在本地,安全便捷 | 类似Cookies,存储临时的简单数据 | 类似Android中的SP |
Web SQL DataBase | 基于SQL | 利用数据库优势,增删改查方便 | 存储复杂、数据量大的结构化数据 | 不推荐使用,用IndexedDB替代 |
IndexedDB | 通过存储键值对实现(NoSQL) | 存储空间大、使用简单灵活 | 存储复杂、数据量大的结构化数据 | 集合Dom Storage和Web SQL DataBase的有点 |
AppCache | 类似浏览器缓存,以文件为单位进行缓存 | 构建方便 | 离线缓存,存储静态资源 | 对浏览器缓存的补充 |
File System | 提供一个虚拟的文件系统 | 可存储二进制数据、预加载资源和之间编辑文件 | 通过文件系统管理数据 | 目前Android不支持 |
有需要以上面试题的朋友可以关注一下哇哇,以上都可以分享!!!