移动端缓存方案

移动端缓存方案

标签(空格分隔): 缓存 移动端


Cache目的

Cache几乎无处不在,iOS系统clean memory、dirty memory,HTTP的tag机制,都是Cache设计思想的应用。
Cache的目的是为了追求更高的速度体验,其源头是两种数据读取方式在成本性能上的差异。


数据存储媒介

Cache的本质,是利用空间换取时间,对数据的存储进行处理。在设计Cache之前,需要先理清数据存储媒介

  • 数据最开始是存储在Server上,需要通过网络请求获取。
  • 从Server获取数据时,会经过各种网络节点,这些节点有时会缓存我们的数据。
  • APP拿到服务器的数据后,临时存储在memory中,有些数据需要存储到disk。
  • Disk中数据的存储方式,会影响到读取的速度;以B+Tree存储的SQLite就比直接序列化Array到文件中快不少。
  • Memory存储中,不同的数据结构存储方式也会存在速度上的差异,hash表形式存储读、写性能都比array好不少,但是空间开销比array大。

对于Cache的理解和实践,需要我们对存储媒介、不同数据结构差异有比较深的掌握


WEB缓存策略

HTTP缓存规则

浏览器端的缓存规则,是在HTTP协议头HTML页面的Meta标签中定义,分别从新鲜度校验值两个维度来规定浏览器是否可以直接使用缓存,还是去服务器获取新的数据。

新鲜度

新鲜度也就是过期规则,缓存副本的有效期。缓存是否有效,需要满足以下两个条件:

  • 含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;
  • 浏览器已经使用过这个缓存,并且在一个会话中已经检查过新鲜度.
校验值

校验值也就是验证机制:服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如果发现校验标识不匹配,说明资源已经被修改或者过期,浏览器需要重新请求获取资源。

HTML缓存策略

离线应用缓存Manifest
  • 用户可以离线访问应用,适用于无法保持联网状态的移动端用户。
  • 用户访问本地缓存文件,意味更快的访问速度
  • 仅仅加载被修改过的资源,避免同一资源对服务器多次请求,降低对服务器的访问压力

Manifest文件清单示例:


LocalStorage

用于代码中的常量保存,代码示例:



iOS缓存策略

Memory Cache - NSCache

Memory Cache的适用场景:数据量小,读写效率要求高,会随着APP被杀死自动释放、或者自定义释放规则。

NSCache使用的几个注意点:

  1. NSCache是苹果官方提供的缓存类,具体使用和NSDictionary相似;
  2. NSCache在系统内存很低时会自动释放,使用的时候需要注意过期规则;
  3. NSCache是线程安全的,在进行多线程操作时,不需要进行加锁。
  4. NSCache的Key是对对象进行了Strong引用,非拷贝。

Disk Cache

iOS本地缓存的几种方式:

  1. NSArray、NSDictionary等数据类型直接写文件到APP的沙盒中,使用场景:图片信息;
  2. NSUserDefault,用来存储应用的设置信息,使用场景:APP颜色、模块配置信息;
  3. NSKeyedArchiver,归档操作,可以把自定义对象存储在文件中,APP中登录结束,用户信息可以作为对象存储,用于下次自动登录。
  4. CoreData,苹果官方推出的综合性数据库,使用ORM对象关系映射技术,将对象转换成数据,存储到本地数据库中,CoreData是完全面向对象的,执行效率相对原生数据库较差。
  5. SQLite,可跨平台,适用于数据量大的场景,常用于APP中列表数据。

Android缓存策略

LRU(Least Recently Used),近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象。Android官方推荐使用LrhCache和DisLruCache作为Android缓存策略的解决方案,分别用于实现内存缓存、硬盘缓存,其核心思想都是LRU缓存算法。

LRU Cache原理

LruCache是个泛型类,主要算法原理是把最近使用的对象用强引用(即我们平常使用的对象引用方式)存储在 LinkedHashMap 中。当缓存满时,把最近最少使用的对象从内存中移除,并提供了get和put方法来完成缓存的获取和添加操作。

LruCache中维护了一个集合LinkedHashMap,该LinkedHashMap是以访问顺序排序的。当调用put()方法时,就会在结合中添加元素,并调用trimToSize()判断缓存是否已满,如果满了就用LinkedHashMap的迭代器删除队尾元素,即近期最少访问的元素。当调用get()方法访问缓存对象时,就会调用LinkedHashMap的get()方法获得对应集合元素,同时会更新该元素到队头。

代码示例:

package com.example.linux.lrucachetest;

import android.graphics.Bitmap;
import android.util.LruCache;

/**
 * Created by huhx on 2016/4/12.
 */
public class ImageDownloader {
    private static final String TAG = "TextDownload";
    private LruCache<String, Bitmap> lruCache;

    public ImageDownloader() {
        long maxMemory = Runtime.getRuntime().maxMemory();
        int cacheSize = (int) (maxMemory / 8);
        lruCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };
    }

    // 把Bitmap对象加入到缓存中
    public void addBitmapToMemory(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            lruCache.put(key, bitmap);
        }
    }

    // 从缓存中得到Bitmap对象
    public Bitmap getBitmapFromMemCache(String key) {
    Log.i(TAG, "lrucache size: " + lruCache.size());
        return lruCache.get(key);
    }

    // 从缓存中删除指定的Bitmap
    public void removeBitmapFromMemory(String key) {
        lruCache.remove(key);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容