android缓存

  在使用ListView,GridView控件时,由于其内部的重用机制,导致item中的内容会被清空,但是如果是网络中下载的内容特别是图片则会比较麻烦,因为经常需要从后台重新加载。为了提高用户体验,需要对图片等数据进行缓存,避免耗时的网络操作。

一、LruCache:android官方提供的用于在内存中进行缓存的一个类。

1     public LruCache(int maxSize) {
2         if (maxSize <= 0) {
3             throw new IllegalArgumentException("maxSize <= 0");
4         }
5         this.maxSize = maxSize;
6         this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
7     }

LruCache构造函数

由构造函数可知,

  1、该缓存系统是使用LinkedHashMap来保存数据的。

  2、需要传入一个int型的数值表示可以存储的最大容量,但是由于存入的数据的类型没有限制,所以添加和删除数据时的size变化就不确定。例如缓存String就可以以个数计算;但是如果存入的是Bitmap,则以其的内存大小计算更合适。!!!所以,在使用该类时通常需要重写其sizeOf(),指定其size变化的规则。

该缓存类实现的效果是:先保存然后进行调整,如果超过容量则将最近最早未被使用的数据删除。

 1     public final V put(K key, V value) {
 2         if (key == null || value == null) {
 3             throw new NullPointerException("key == null || value == null");
 4         }
 5
 6         V previous;
 7         //该同步块中执行put操作,并对size进行调整,一种是覆盖原有key,一种是新建
 8         synchronized (this) {
 9             putCount++;
10             size += safeSizeOf(key, value);
11             previous = map.put(key, value);
12             if (previous != null) {
13                 size -= safeSizeOf(key, previous);
14             }
15         }
16
17         if (previous != null) {
18             entryRemoved(false, key, previous, value);
19         }
20
21         //该方法是对总容量的调整:如果超过则删除离header最近的元素,直到小于总容量
22         trimToSize(maxSize);
23         return previous;
24     }
25
26     public void trimToSize(int maxSize) {
27         while (true) {
28             K key;
29             V value;
30             synchronized (this) {
31                 if (size < 0 || (map.isEmpty() && size != 0)) {
32                     throw new IllegalStateException(getClass().getName()
33                             + ".sizeOf() is reporting inconsistent results!");
34                 }
35
36                 if (size <= maxSize) {
37                     break;
38                 }
39
40                 //获取最早保存的数据进行删除
41                 Map.Entry<K, V> toEvict = map.eldest();
42                 if (toEvict == null) {
43                     break;
44                 }
45
46                 key = toEvict.getKey();
47                 value = toEvict.getValue();
48                 map.remove(key);
49                 size -= safeSizeOf(key, value);
50                 evictionCount++;
51             }
52
53             entryRemoved(true, key, value, null);
54         }
55     }

LruCache的put()

二、DiskLruCache:官方认证的硬盘缓存方式,不是android的API,需要下载才能使用。

  1、首先是创建过程,该类不能直接创建,需要通过open方法进行创建,

 1    /* @param directory         缓存路径,
 2    * @param valueCount       每个缓存实体对应的缓存数量,通常是1
 3    * @param maxSize           最大缓存容量
 4    */
 5
 6 //一个用户获取可用的缓存路径的方法,首先是外部存储器,然后是内部存储器
 7 public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
 8
 9 public File getDiskCacheDir(Context context, String uniqueName) {
10     String cachePath;
11     if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
12             || !Environment.isExternalStorageRemovable()) {
13         cachePath = context.getExternalCacheDir().getPath();
14     } else {
15         cachePath = context.getCacheDir().getPath();
16     }
17     return new File(cachePath + File.separator + uniqueName);
18 }
19
20 //获取应用版本号的方法
21     public int getAppVersion(Context context) {
22         try {
23             PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
24             return info.versionCode;
25         } catch (NameNotFoundException e) {
26             e.printStackTrace();
27         }
28         return 1;
29     }

  2、写入缓存:通过DiskLruCache.Editor来操作的,创建该类使用的是edit(),

1 //参数key将作为该缓存的名字,为将请求url和其对应,通常使用md5对其操作生成唯一字符串
2   public Editor edit(String key) throws IOException {
3     return edit(key, ANY_SEQUENCE_NUMBER);
4   }

    创建一个Editor之后就可以通过它生成一个输出流,向缓存文件中进行输出操作。

  3、读取缓存:通过DiskLruCache的get()可以获取一个Snapshot对象,该对象中包含着这个缓存文件的输出流,可以对流进行读取获取其中的缓存。

  4、其他操作:

    ①移除缓存:remove()

    ②获取缓存大小:size()

    ③通过缓存操作到日志文件(也就是journal文件),通常在Activity的onPause()中调用一次即可。

    ④清空缓存:delete()

    ⑤关闭缓存:close(),和open()对应。

时间: 2024-10-18 19:30:01

android缓存的相关文章

Android Studio编译运行Fresco Sample。Android缓存新境界。 (a problem occurred start process &#39;command &#39;ndk-build&#39;&#39;)

今天闲逛知乎,偶遇一篇“Android应用开发难点”,作为安卓程序猿,本能点进去,想看看究竟能有什么难点自己不知道的(夜郎自大..面壁中). 插件化,H5容器优化,网络.图片缓存..感觉都还好.直到看到“Fresco出来之前,你是不是觉得图片缓存已经到头了?” Fresco究竟是何方神圣!! 询问度娘得知,2015.3.27日之前就已经发布了(度娘的结果最早是3.27).通过查看GitHub: Version 0.1.0  tyronen released this 16 days ago · 

android 缓存路径

用程序在运行的过程中如果需要向手机上保存数据,一般是把数据保存在SDcard中的.大部分应用是直接在SDCard的根目录下创建一个文件夹,然后把数据保存在该文件夹中.这样当该应用被卸载后,这些数据还保留在SDCard中,留下了垃圾数据.如果你想让你的应用被卸载后,与该应用相关的数据也清除掉,该怎么办呢? 通过Context.getExternalFilesDir()方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据通过Conte

Android缓存机制&amp;一个缓存框架推荐

1.先推荐一个轻量级缓存框架--ACache(ASimpleCache) ACache介绍: ACache类似于SharedPreferences,但是比SharedPreferences功能更加强大,SharedPreferences只能保存一些基本数据类型.Serializable.Bundle等数据, 而Acache可以缓存如下数据: 普通的字符串.JsonObject.JsonArray.Bitmap.Drawable.序列化的java对象,和 byte数据. 主要特色: 1:轻,轻到只

[小记]Android缓存问题

今天晚上,产品经理打电话说我们的Android App除了问题,问题很简单就是一个缓存问题,由于这个程序是前同事写的,我也只能呵呵一笑,有些事你就得扛.还是回到正题吧,这个缓存问题,实在有点奇葩,所以我才要记录下,希望避免 问题 看了代码,感觉上没问题,不过针对用户出现的问题,还是觉得这个逻辑就是错误的: 1 有文件缓存就不在请求网络 由于请求的那个接口返回的数据较大,做了一个文件缓存放到本地,这个没错,可是缓存完后,当下次在请求,居然先判断缓存文件是否存在,若存在就不在读取网络数据,而是直接用

Android 缓存

1.Android缓存机制&一个缓存框架推荐 http://blog.csdn.net/shakespeare001/article/details/51695358 2.ASimpleCache https://github.com/yangfuhai/ASimpleCache 3.Android DiskLruCache 源码解析 硬盘缓存的绝佳方案 4.Android DiskLruCache完全解析,硬盘缓存的最佳方案 5.DiskLruCache https://github.com/

由Android缓存设计想到的

由Android缓存设计想到的 前言 Android这种对内存比较敏感的系统,在处理大量图片的时候不可避免要用到缓存,那么到底是应该使用虚拟机底层通过GC回收保障的SoftReference,还是使用一个带LRU算法的队列,哪个更适合Android系统下的应用? 基本概念 缓存,顾名思义把已经读取到的数据存下来,供再次读取,合理的使用缓存可以减少一些昂贵代价的动作(数据库操作,文件读写,网络传输,等),缓解系统压力,提高程序响应速度. 设计缓存需要注意的几个方面:缓存的容量,如何使缓存维持在一个

Android 缓存处理

Android缓存: 采用缓存,可以进一步大大缓解数据交互的压力,又能提供一定的离线浏览.下边我简略列举一下缓存管理的适用环境: 1. 提供网络服务的应用 2. 数据更新不需要实时更新,哪怕是3-5分钟的延迟也是可以采用缓存机制. 3. 缓存的过期时间是可以接受的(类似网易的新闻阅读,支持离线离线阅读) 这样所带来的好处: 1. 减小服务器的压力 2. 提高客户端的响应速度(本地数据提取嘛) 3. 一定程度上支持离线浏览(可以参考网易的那个新闻应用,个人感觉离线阅读做得非常棒.) 一.缓存管理的

android缓存详解

Android缓存: 采用缓存,可以进一步大大缓解数据交互的压力,又能提供一定的离线浏览.下边我简略列举一下缓存管理的适用环境: 1. 提供网络服务的应用 2. 数据更新不需要实时更新,哪怕是3-5分钟的延迟也是可以采用缓存机制. 3. 缓存的过期时间是可以接受的(类似网易的新闻阅读,支持离线离线阅读) 这样所带来的好处: 1. 减小服务器的压力 2. 提高客户端的响应速度(本地数据提取嘛) 3. 一定程度上支持离线浏览(可以参考网易的那个新闻应用,个人感觉离线阅读做得非常棒.) 一.缓存管理的

【转】彻底解析Android缓存机制——LruCache

彻底解析Android缓存机制——LruCache 关于Android的三级缓存,其中主要的就是内存缓存和硬盘缓存.这两种缓存机制的实现都应用到了LruCache算法,今天我们就从使用到源码解析,来彻底理解Android中的缓存机制. 一.Android中的缓存策略 一般来说,缓存策略主要包含缓存的添加.获取和删除这三类操作.如何添加和获取缓存这个比较好理解,那么为什么还要删除缓存呢?这是因为不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限的.当缓存满了之后,再想其添加缓存,这个时候就需要删除

Android缓存处理--&gt;

采用缓存,可以进一步大大缓解数据交互的压力,又能提供一定的离线浏览. 缓存管理的适用环境: 1. 提供网络服务的应用 2. 数据更新不需要实时更新,哪怕是3-5分钟的延迟也是可以采用缓存机制. 3. 缓存的过期时间是可以接受的(类似网易的新闻阅读,支持离线离线阅读) 这样所带来的好处: 1. 减小服务器的压力 2. 提高客户端的响应速度(本地数据提取嘛) 3. 一定程度上支持离线浏览(可以参考网易的那个新闻应用,个人感觉离线阅读做得非常棒.) 缓存管理的原理:通过时间的设置来判断是否读取缓存还是