Android缓存学习入门(二)

本文主要包括以下内容

  1. 内存缓存策略
  2. 文件缓存策略

内存缓存策略

当有一个图片要去从网络下载的时候,我们并不会直接去从网络下载,因为在这个时代,用户的流量是宝贵的,耗流量的应用是不会得到用户的青睐的。那我们该怎么办呢?这样,我们会先从内存缓存中去查找是否有该图片,如果没有就去文件缓存中查找是否有该图片,如果还没有,我们就从网络下载图片。本博文的侧重点是如何做内存缓存,内存缓存的查找策略是:先从强引用缓存中查找,如果没有再从软引用缓存中查找,如果在软引用缓存中找到了,就把它移入强引用缓存;如果强引用缓存满了,就会根据Lru算法把某些图片移入软引用缓存,如果软引用缓存也满了,最早的软引用就会被删除。这里,我有必要说明下几个概念:强引用、软引用、弱引用、Lru。

  • 强引用:就是直接引用一个对象,一般的对象引用均是强引用
  • 软引用:引用一个对象,当内存不足并且除了我们的引用之外没有其他地方引用此对象的情况 下,该对象会被gc回收
  • 弱引用:引用一个对象,当除了我们的引用之外没有其他地方引用此对象的情况下,只要gc被调用,它就会被回收(请注意它和软引用的区别)
  • Lru:Least Recently Used 近期最少使用算法,是一种页面置换算法,其思想是在缓存的页面数目固定的情况下,那些最近使用次数最少的页面将被移出,对于我们的内存缓存来说,强引用缓存大小固定为4M,如果当缓存的图片大于4M的时候,有些图片就会被从强引用缓存中删除,哪些图片会被删除呢,就是那些近期使用次数最少的图片。

注意

In the past, a popular memory cache implementation was a SoftReference or WeakReference bitmap cache, however this is not recommended. Starting from Android 2.3 (API Level 9) the garbage collector is more aggressive with collecting soft/weak references which makes them fairly ineffective. In addition, prior to Android 3.0 (API Level 11), the backing data of a bitmap was stored in native memory which is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash.

在android2.3之后,软引用与弱引用已经不可靠了,所以慎用。

public class ImageMemoryCache {/*** 从内存读取数据速度是最快的,为了更大限度使用内存,这里使用了两层缓存。*  强引用缓存不会轻易被回收,用来保存常用数据,不常用的转入软引用缓存。*/private static final String TAG = "ImageMemoryCache";private static LruCache<String, Bitmap> mLruCache; // 强引用缓存private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache; // 软引用缓存private static final int LRU_CACHE_SIZE = 4 * 1024 * 1024; // 强引用缓存容量:4MBprivate static final int SOFT_CACHE_NUM = 20; // 软引用缓存个数// 在这里分别初始化强引用缓存和弱引用缓存public ImageMemoryCache() {mLruCache = new LruCache<String, Bitmap>(LRU_CACHE_SIZE) {@Override// sizeOf返回为单个hashmap value的大小protected int sizeOf(String key, Bitmap value) {if (value != null)return value.getRowBytes() * value.getHeight();elsereturn 0;}@Overrideprotected void entryRemoved(boolean evicted, String key,Bitmap oldValue, Bitmap newValue) {if (oldValue != null) {// 强引用缓存容量满的时候,会根据LRU算法把最近没有被使用的图片转入此软引用缓存Logger.d(TAG, "LruCache is full,move to SoftRefernceCache");mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));}}};mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(SOFT_CACHE_NUM, 0.75f, true) {private static final long serialVersionUID = 1L;/*** 当软引用数量大于20的时候,最旧的软引用将会被从链式哈希表中移出*/@Overrideprotected boolean removeEldestEntry(Entry<String, SoftReference<Bitmap>> eldest) {if (size() > SOFT_CACHE_NUM) {Logger.d(TAG, "should remove the eldest from SoftReference");return true;}return false;}};}/*** 从缓存中获取图片*/public Bitmap getBitmapFromMemory(String url) {Bitmap bitmap;// 先从强引用缓存中获取synchronized (mLruCache) {bitmap = mLruCache.get(url);if (bitmap != null) {// 如果找到的话,把元素移到LinkedHashMap的最前面,从而保证在LRU算法中是最后被删除mLruCache.remove(url);mLruCache.put(url, bitmap);Logger.d(TAG, "get bmp from LruCache,url=" + url);return bitmap;}}// 如果强引用缓存中找不到,到软引用缓存中找,找到后就把它从软引用中移到强引用缓存中synchronized (mSoftCache) {SoftReference<Bitmap> bitmapReference = mSoftCache.get(url);if (bitmapReference != null) {bitmap = bitmapReference.get();if (bitmap != null) {// 将图片移回LruCachemLruCache.put(url, bitmap);mSoftCache.remove(url);Logger.d(TAG, "get bmp from SoftReferenceCache, url=" + url);return bitmap;} else {mSoftCache.remove(url);}}}return null;}/*** 添加图片到缓存*/public void addBitmapToMemory(String url, Bitmap bitmap) {if (bitmap != null) {synchronized (mLruCache) {mLruCache.put(url, bitmap);}}}public void clearCache() {mSoftCache.clear();}
}

文件缓存策略

当一张图片从网络下载成功以后,这个图片会被加入内存缓存和文件缓存,对于文件缓存来说,这张图片将被以url的哈希值加cach后缀名的形式存储在SD卡上,这样,当下一次再需要同一个url的图片的时候,就不需要从网络下载了,而是直接通过url来进行查找。同时一张图片被访问时,它的最后修改时间将被更新,这样的意义在于:当SD卡空间不足的时候,将会按照最后修改时间来删除40%缓存的图片,确切来说,那些修改时间比较早的图片将会被删除。

public class ImageFileCache
{private static final String TAG = "ImageFileCache";//图片缓存目录private static final String IMGCACHDIR = "/sdcard/ImgCach";//保存的cache文件宽展名private static final String CACHETAIL = ".cach";private static final int MB = 1024*1024;private static final int CACHE_SIZE = 1;//当SD卡剩余空间小于10M的时候会清理缓存private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;public ImageFileCache() {//清理部分文件缓存removeCache(IMGCACHDIR);            }/** * 从缓存中获取图片 */public Bitmap getImageFromFile(final String url) {    final String path = IMGCACHDIR + "/" + convertUrlToFileName(url);File file = new File(path);if (file != null && file.exists()) {Bitmap bmp = BitmapFactory.decodeFile(path);if (bmp == null) {file.delete();} else {updateFileTime(path);Logger.d(TAG, "get bmp from FileCache,url=" + url);return bmp;}}return null;}/*** 将图片存入文件缓存 */public void saveBitmapToFile(Bitmap bm, String url) {if (bm == null) {return;}//判断sdcard上的空间if (FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace()) {//SD空间不足return;}String filename = convertUrlToFileName(url);File dirFile = new File(IMGCACHDIR);if (!dirFile.exists())dirFile.mkdirs();File file = new File(IMGCACHDIR +"/" + filename);try {file.createNewFile();OutputStream outStream = new FileOutputStream(file);bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);outStream.flush();outStream.close();} catch (FileNotFoundException e) {Logger.d(TAG, "FileNotFoundException");} catch (IOException e) {Logger.d(TAG, "IOException");}} /*** 计算存储目录下的文件大小,* 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定* 那么删除40%最近没有被使用的文件*/private boolean removeCache(String dirPath) {File dir = new File(dirPath);File[] files = dir.listFiles();if (files == null) {return true;}if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){return false;}int dirSize = 0;for (int i = 0; i < files.length; i++) {if (files[i].getName().contains(CACHETAIL)) {dirSize += files[i].length();}}if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace()) {int removeFactor = (int) (0.4 * files.length);Arrays.sort(files, new FileLastModifSort());for (int i = 0; i < removeFactor; i++) {if (files[i].getName().contains(CACHETAIL)) {files[i].delete();}}}if (SdCardFreeSpace() <= CACHE_SIZE) {return false;}return true;}/*** 修改文件的最后修改时间*/public void updateFileTime(String path) {File file = new File(path);long newModifiedTime = System.currentTimeMillis();file.setLastModified(newModifiedTime);}/** * 计算SD卡上的剩余空间 */private int SdCardFreeSpace(){StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;return (int) sdFreeMB;} /** * 将url转成文件名 */private String convertUrlToFileName(String url){return url.hashCode() + CACHETAIL;}/*** 根据文件的最后修改时间进行排序*/private class FileLastModifSort implements Comparator<File> {public int compare(File file0, File file1) {if (file0.lastModified() > file1.lastModified()){return 1;} else if (file0.lastModified() == file1.lastModified()) {return 0;} else {return -1;}}}}

References

android中图片的三级cache策略(内存、文件、网络)之二:内存缓存策略

android中图片的三级cache策略(内存、文件、网络)之三:文件缓存策略

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494009.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本届诺奖得主“牛”在哪儿?专业数据分析给出论文干货

来源&#xff1a;科技日报摘要&#xff1a;北京时间10月2日下午5时52分&#xff0c;2018年诺贝尔物理学奖揭晓。获奖者为美国科学家阿瑟阿什金&#xff08;Arthur Ashkin&#xff09;、法国科学家热拉尔穆鲁&#xff08;Gerard Mourou&#xff09;和加拿大科学家唐娜斯特里克兰…

码农老婆的网店

码农老婆的网店&#xff1a;清泓美肤苑 转载于:https://www.cnblogs.com/8090sns/p/3162690.html

130701基础练习-first

// 629.cpp : 定义控制台应用程序的入口点。// #include "stdafx.h"//#include <iostream.h> class Point{public: void OutPut() { int a2; printf("Please output a integer:\n"); printf("%d",a); scanf("%d",&a); }…

联合国发布AI报告:自动化和AI对亚洲有巨大影响【附报告下载】

来源&#xff1a;网易智能选自 | 联合国开发计划署编译 | nariiy、小小科技的飞速发展将深刻地影响社会变革&#xff0c;第四次工业革命以人工智能、自动化和生物科技等创新技术为代表&#xff0c;并将可能改变现有的生产、管理和治理体系&#xff0c;各国将如何接受并适应即将…

对PostgreSQL cmin和cmax的理解

看例子&#xff1a; 开两个终端来对比&#xff1a; 在终端A: [pgsqllocalhost bin]$ ./psql psql (9.1.2) Type "help" for help.pgsql# begin; BEGIN pgsql# select xmin,xmax,cmin,cmax,* from tab01;xmin | xmax | cmin | cmax | id | cd ---------------…

关于自动驾驶汽车法律政策的十点思考

来源&#xff1a;智车科技摘要&#xff1a;自动驾驶技术的发展将带来全面的社会和经济影响。历史地看&#xff0c;传统汽车成为了人们最主要的代步工具&#xff0c;塑造了如今的城市。那么&#xff0c;自动驾驶技术在重塑汽车的同时&#xff0c;也将塑造未来的城市和人类生活。…

数据结构之二叉堆

二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树&#xff0c;按照数据的排列方式可以分为两种&#xff1a;最大堆和最小堆。 最大堆&#xff1a;父结点的键值总是大于或等于任何一个子节点的键值&#xff1b; 最小堆&#xff1a;父结点的键值总是小于或等于任何一个子…

derby数据库操作比较难理解的错误及解决方法大全

一、插入&#xff08;INSERT时报错&#xff09; 1、错误&#xff1a;java.sql.SQLIntegrityConstraintViolationException: 列“test”无法接受空值。 可能原因&#xff1a;建表时test列为not null 但插入数据时给与了null值 2、错误&#xff1a;java.sql.SQLSyntaxErrorExcept…

手术革命:这三家公司如何用AR技术辅助医疗手术

来源&#xff1a;资本实验室作为一种重要的职业&#xff0c;外科医生特别是手术医生需要具备丰富的专业知识&#xff0c;还需要掌握精准的手术操作技术&#xff0c;这都需要不断的学习与练习。受学习资料、手术练习材料等软硬件条件的制约&#xff0c;医生进行手术学习和手术操…

C# Socket初探

闲着无聊&#xff0c;写了个简单的C/S Socket程序&#xff0c;功能很简单&#xff0c;服务器在9000端口监听socket接入&#xff0c;只要有接入&#xff0c;就发送"Welcome."消息给客户端。 代码分2块&#xff0c;server端&#xff1a; class Program{static void Mai…

最新发布 | 2018年度第八届吴文俊人工智能科学技术奖获奖名单公示

来源&#xff1a;人工智能人物摘要&#xff1a;2018年度第八届吴文俊人工智能科学技术奖评审工作已经完成。根据《吴文俊人工智能科学技术奖励条例》和《吴文俊人工智能科学技术奖励实施细则》相关规定&#xff0c;经全国各地方人工智能学会、各高校及科研院所、团体会员单位和…

ReactNative环境配置

参考链接 Windows系统安装React Native环境 windows下React Native Android 环境搭建 在Windows下搭建React Native Android开发环境 碰到的问题 react-native可能在cmd窗口提示不是内部或外部命令 解决方法&#xff1a;在nodeJS command prompt下可以运行 运行时卡在最…

qt.pro转成vs程序

今天下载了一个smarthome项目&#xff0c;界面用qml实现的&#xff0c; 想用vs编译生成.exe文件&#xff0c;在wince上运行 方法一&#xff08;vs命令行&#xff09;: 一: 打开vs 2008 命令行&#xff0c;进入smarthome目录下&#xff1a; 二: qmake生成 smarthome.vcproj工程…

DNA存储:这些公司正在开启数据存储的未来

来源&#xff1a;资本实验室随着数字化时代的到来&#xff0c;可以毫不夸张地说&#xff0c;数据存储与安全正在成为整个社会正常运行的基础。同时&#xff0c;物联网、人工智能、虚拟现实、自动驾驶等新技术的应用则进一步大幅提升了数据存储要求。据IDC预测&#xff0c;到202…

React基础语法学习

React主要有如下3个特点&#xff1a; 作为UI&#xff08;Just the UI&#xff09;虚拟DOM&#xff08;Virtual DOM&#xff09;:这是亮点 是React最重要的一个特性 放进内存 最小更新的视图,差异部分更新 diff算法数据流&#xff08;Date Flow&#xff09;单向数据流 学习Re…

C#中ListT用法

所属命名空间&#xff1a;System.Collections.Generic public classList<T> :IList<T>,ICollection<T>,IEnumerable<T>,IList,ICollection,IEnumerable List<T>类是ArrayList类的泛型等效类。该类使用大小可按需动态增加的数组实现IList<…

算力超英伟达?华为推出两款“昇腾”芯片;五大AI战略正式公布

来源&#xff1a;AI科技大本营华为也像是要 All in AI 了。10 月 10 日&#xff0c;华为全联接大会 2018 上&#xff0c;华为轮值董事长徐直军带来了一系列的硬核 AI。在大会上&#xff0c;他系统公布了华为的 AI 发展战略&#xff0c;以及全栈全场景 AI 解决方案&#xff0c;其…

Qt5:渐变效果的实现

http://devbean.blog.51cto.com/448512/238168/ 转载于:https://www.cnblogs.com/wowk/p/3174602.html

React之JSX入门

React是由ReactJS与React Native组成&#xff0c;其中ReactJS是Facebook开源的一个前端框架&#xff0c;React Native 是ReactJS思想在native上的体现&#xff01; JSX并不是一门新的语言&#xff0c;仅仅是个语法糖&#xff0c;允许开发者在JavaScript中书写HTML语法。&…

英特尔人工智能副总裁:AI不是一种技能,而是一种对于工作的描述

来源&#xff1a;网络大数据人工智能领域的迅速发展&#xff0c;相关人才不能满足需求已经成为业界共识。有报道称&#xff0c;因为人工智能工程师庞大的缺口&#xff0c;一些公司为了获得人才不得不支付数百万美元的薪水。如何满足对人工智能工程师不断增长的招聘和培训的需求…