DiskLruCache磁盘缓存
来源:互联网 发布:wps表格查找重复数据 编辑:程序博客网 时间:2024/04/29 11:47
1.DiskLruCache的创建
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)使用此方法创建DiskLruCache,此方法共接收四个参数
第一个参数表示磁盘缓存在文件系统中的路径,具体为/sdcard/Android/data/package_name/cache目录,其中package_name为应用程序的包名,当应用程序被卸载后此目录会一并删除。
获取磁盘缓存在文件系统中的路径具体代码:
public File getDiskCacheDir(Context context,String uniqueName){ String cachePath; //判断sd卡是否有读写权限,是否可被移除;当具有读写权限或者不可被移除,使用前者;否则使用后者 if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageSt ate())||!Environment.isExternalStorageRemovable(){ //获取缓存路径; cachePath = context.getExternalCacheDir().getPath(); }else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath+File.separator+uniqueName);}
前者获取的路径为:/sdcard/Android/data/package_name/cache后者获取的路劲为: /data/data/package_name/cache,uniqueName为某一类型的数据的值,如图片类型可设置为bitmap,则最终获取的缓存路径为:/sdcard/Android/data/package_name/cache/bitmap
第二个参数为应用的版本号一般设置为1即可,当版本发生改变时会清空之前的缓存文件。
第三个参数为单个节点所对应的数据个数,设置为1即可,第四个参数表示缓存容器的总大小,如50MB,当需要缓存的文件超过该值时会自动清除部分缓存,从而保证缓存文件的大小不超过该缓存容器的大小。
创建一个open()可写为:
File cacheDir = getDiskCacheDir(context,"bitmap");if(!cacheDir.exists()){ //如果不存在,创建此文件夹 cacheDir.mkdirs();}try{ mDiskLruCache = DiskLruCache.open(cacheDir,1,1,50*1024*1024);} catch (IOException e) { e.printStackTrace();}
获取DiskLruCache实例后,接着就可以写入缓存
首先下载一张图片如http://img.my.csdn.NET/uploads/201309/01/1378037235_7476.jpg
private boolean downLoadUrlToStream(String url, final OutputStream outputStream){ OkHttpClient mOkHttpClient = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); BufferedInputStream in = null; BufferedOutputStream out = null; try { Response response = mOkHttpClient.newCall(request).execute(); InputStream inputStream = response.body().byteStream(); in = new BufferedInputStream(inputStream, 8 * 1024); out= new BufferedOutputStream(outputStream, 8 * 1024); int b; while ((b = in.read()) != -1) { out.write(b); } return true; }catch (IOException e) { e.printStackTrace(); }finally { if(out!=null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } if (in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } return false;}
DiskLruCache缓存的添加是通过Editor完成,然后将图片的url转化为key,根据key然后调用edit(String key),可以获取Editor对象,然后调用Editor对象的newOutputStream(int index)方法即可获取OutputStream对象,得到OutputStream对象和url后,使用上述downLoadUrlToStream(String url, final OutputStream outputStream),就可以将图片进行写入,但此时并没有写入文件系统还需调用Editor的commit()方法。
由于url中可能包含特殊字符,使其不能直接作为key,因此可使用MD5编码使其转化为key;
public static String hashKeyForUrl(String url){ String catchKey; try { final MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(url.getBytes()); catchKey = bytesToHexString(mDigest.digest()); } catch (NoSuchAlgorithmException e) { catchKey = String.valueOf(url.hashCode()); } return catchKey; } private static String bytesToHexString(byte[] bytes){ StringBuilder sb = new StringBuilder(); for (int i =0;i<bytes.length;i++){ String hex = Integer.toHexString(0XFF&bytes[i]); if(hex.length()==1){ sb.append(0); } sb.append(hex); } return sb.toString(); }
然后就可以获取Editor对像,并进行写入磁盘操作
public void ImageLoading(){ new Thread(new Runnable() { @Override public void run() { String url = "http://img.my.csdn.net/uploads/201309/01/1378 037235_7476.jpg"; String key = hashKeyForUrl(url); try { DiskLruCache.Editor editor = mDiskLruCache.edit(key); if(editor!=null){ OutputStream outputStream = editor.newOutputStream( 0); if(downLoadUrlToStream(url,outputStream)){ //进行写入操作 editor.commit(); }else { //下载过程中出现异常退出操作 editor.abort(); } } //这个方法用于将内存中的操作记录同步到日志文件(也就是journal文 件)当中。 mDiskLruCache.flush(); } catch (IOException e) { e.printStackTrace(); } } }).start(); }
读取缓存
缓存读取也需要将url转化为key,按照MD5上述编码方式转化即可。然后通过DiskLruCache的get(String key)方法获取Snapshot对象,接着通过Snapshot对象的getInputStream(int index)即可获取InputStream,然后就可以获取Bitmap对象。为了避免OOM需要对图片压缩后,再将其显示在ImageView上面。
Bitmap bitmap = null;String url = "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg";String key = hashKeyForUrl(url);DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);if (snapshot != null) { FileInputStream fileInputStream = (FileInputStream) snapshot.getInputSt ream(0); //获取文件流对应的文件描述符 FileDescriptor fileDescriptor = fileInputStream.getFD(); //把图片压缩成100*100像素 bitmap = decodeBitmapFromFileDescriptor(fileDescriptor, 100,100);}
图片压缩
public static Bitmap decodeBitmapFromFileDescriptor(FileDescriptor fileDescriptor,int reqWidth,int reqHeight){ final BitmapFactory.Options options = new BitmapFactory.Options(); //inJustDecodeBounds 设置为true时BitmapFactory只会解析原始图片宽高,不会加载 图片 options.inJustDecodeBounds = true; BitmapFactory.decodeFileDescriptor(fileDescriptor,null,options); options.inSampleSize = calculateInSampleSize(options,reqWidth,reqHeigh t); //当希望获取Bitmap实例时需要设置inJustDecodeBounds为false; options.inJustDecodeBounds = false; return BitmapFactory.decodeFileDescriptor(fileDescriptor,null,options);}public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){ //获取原始图片的宽高 final int realWidth = options.outWidth; final int realHeight = options.outHeight; //定义采样率; int inSampleSize = 1; if(realHeight>reqHeight||realWidth>reqWidth){ final int halfHeight = realHeight/2; final int halfWidth = realWidth/2; while ((halfHeight/inSampleSize)>=reqHeight&&(halfWidth/inSampleSize )>=reqWidth){ inSampleSize*=2; } } return inSampleSize;}
压缩图片时由于是FileInputStream方式,FileInputStream是一种有序的文件流,两次调用decodeStream影响了文件流的位置属性,导致第二次调用时返回null,为了解决此问题可以使用文件流对应的文件描述符,然后再进行加载。
Android DiskLruCache完全解析,硬盘缓存的最佳方案
- Android DiskLruCache磁盘缓存
- 磁盘缓存 DiskLruCache
- Android 磁盘缓存 DiskLruCache
- 磁盘缓存DiskLruCache源码
- DiskLruCache磁盘缓存
- Android DiskLruCache(磁盘缓存)
- Android DiskLruCache(磁盘缓存)
- Android DiskLruCache(磁盘缓存)
- DiskLruCache磁盘图片缓存分析
- Android使用磁盘缓存DiskLruCache
- DiskLruCache磁盘缓存的使用介绍
- 磁盘缓存的使用DiskLruCache类
- Android缓存机制Lrucache内存缓存和DiskLruCache磁盘缓存
- Android Volley图片缓存机制结合DiskLruCache实现磁盘缓存
- android网络相册(带磁盘缓存DiskLruCache 和内存缓存LruCache)
- 使用LruCache和DiskLruCache实现内存磁盘二级图片缓存
- 磁盘缓存DiskLruCache的使用与源码分析
- Android DiskLruCache磁盘缓存完全解析及使用
- java单例模式学习
- leetcode(1)
- Linux CentOS 7安装GNOME图形界面并设置默认启动方式
- Maven技术小结
- vim常用命令总结(转)
- DiskLruCache磁盘缓存
- es6中Map结构相关
- cips2016-中文信息处理发展阅读笔记
- MATLAB面向对象编程中类的默认优先级
- 勒索病毒工作原理
- Java Map集合使用方法介绍(2)——商品信息管理
- Spring_使用XML配置文件进行读取
- java io默认目录
- 解决浏览器不能上google的问题