经常使用的内存缓存是软引用和弱引用,大部分的使用方式是Android提供的LRUCache缓存策略,本质是个LinkedHashMap(会根据使用次数进行排序)java
DiskLruCache:非谷歌官方编写,可是得到官方认证android
getCacheDir()是获取app在手机内部存储的cache目录
getFilesDir()是获取app在手机内部存储的files目录算法
经过Context.getExternalFilesDir()能够获取到app在sdcard上的files目录,一般用于存放要长时间保存的数据
经过Context.getExternalCacheDir()能够获取到app在sdcard上的cache目录,一般用于存放一些临时数据
使用上面两个api,在app被卸载的时候,在sdcard上对应的全部文件也会自动被删除,不会留下垃圾信息
并且上面两个目录在设置里的应用详情里,可使用清除数据和清除缓存来清理临时文件api
LRU(Least Recently Used)缓存算法,近期最少使用的算法
LruCache是Android 3.1之后提供的一个缓存类数组
LruCache的缓存大小通常为当前进程可用容量的1/8
重写sizeOf方法,计算每一个缓存对象的大小
注意:缓存的总容量和每一个缓存对象的大小所用的单位要一致缓存
在构造函数中,可使用accessOrder参数来控制双向链表的结构是访问顺序仍是插入顺序
其中accessOrder设置为true则为访问顺序,为false,则为插入顺序。
设置LinkedHashMap的accessOrder为true,并向里面插入数据后随机访问数据,将访问数据后的LinkedHashMap输出,最近访问数据的最后输出网络
LruCache内部使用LinkedHashMap的访问顺序特性,来缓存数据
当调用put()方法时,就会在集合中添加元素,并调用trimToSize()来判断缓存是否已满,若是满了就删除队尾元素
当调用get()方法时,就会调用LinkedHashMap的get()方法得到对应的元素,同时会更新该元素到队首数据结构
DiskLruCache目前还不是Android SDK的一部分,可是Android官方文档推荐使用该算法来实现磁盘缓存app
DiskLruCache不能new出实例,须要调用它的open()方法
open()方法接收四个参数:函数
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
- directory:数据的缓存地址
- appVersion:当前应用程序的版本号
- valueCount:同一个key能够对应多少个缓存文件,基本都是传1
- maxSize:最多能够缓存多少字节的数据
public File getDiskCacheDir(Context context, String uniqueName) { String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); }
能够看到,当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,不然就调用getCacheDir()方法来获取缓存路径。前者获取到的就是 /sdcard/Android/data/
接着是应用程序版本号,咱们可使用以下代码简单地获取到当前应用程序的版本号:
public int getAppVersion(Context context) { try { PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return info.versionCode; } catch (NameNotFoundException e) { e.printStackTrace(); } return 1; }
DiskLruCache mDiskLruCache = null; try { File cacheDir = getDiskCacheDir(context, "bitmap"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024); } catch (IOException e) { e.printStackTrace(); }
插入使用DiskLruCache.Editor这个类来完成,一样,它也不能new出实例,须要使用edit()方法
public Editor edit(String key) throws IOException
// get()方法要求传入一个key来获取到相应的缓存数据,而这个key毫无疑问就是将图片URL进行MD5编码后的值了 public synchronized Snapshot get(String key) throws IOException
public synchronized boolean remove(String key) throws IOException
参考文档:
http://blog.csdn.net/guolin_blog/article/details/28863651
http://blog.csdn.net/guolin_blog/article/details/34093441