Android缓存技术
来源:互联网 发布:怎样在淘宝网上开店铺 编辑:程序博客网 时间:2024/06/13 07:47
原文地址
缓存是现在
Android
开发中很经常碰到的一项技术.通常,缓存会分为两种:内存缓存和磁盘缓存,那么今天介绍的两个类:LruCache
和diskLruCache
分别对应内存缓存和磁盘缓存,关于缓存,图片处理,异步任务,自定义ViewGroup
等几样高级技术我会出一篇关于这几样技术的结合使用.那么今天的缓存是作为其中的一个先行课,主要就是介绍这两个类的使用.
LruCache
这个类用作内存缓存,根据缩写我们应该就可以猜出这个采用了最近最少使用算法.其实这个类的用法相当简单,因为本身通常对于缓存我们主要操作就是两个:
- 把要缓存的对象放入缓存中
- 从缓存中拿出对象
而,对于缓存对象我们是通过键值对去标记的.那么,针对这两个操作,我们实例讲解一下如何使用这个类.
###创建缓存
首先,使用这个类之前我们得先创建类.而创建这个类通常我们要去重写一个函数:sizeOf
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); int cacheSize = maxMemory / 8; memoryCache = new LruCache<String, Bitmap>(cacheSize) { //计算每一个缓存对象的大小 @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } };
如上,一般我们会使用当前可用内存的1/8
的内存作为缓存,在创建LruCache
中我们指定了缓存的对象是bitmap
,而且我们使用String
类型去唯一标示每一个bitmap
对象.然后我们重写sizeOf
函数,这个函数是计算每一个缓存对象的大小,从上面的代码也可以看出这点,不过这里我们要注意单位,cacheSize
和sizeOf
的单位应该要一样.
获取缓存
上面,我们已经建立缓存对象,并且开辟了控件作为缓存,现在我们来看看如何使用缓存.
把图片放入缓存
memoryCache.put("test",bitmap);
如上,我们只要给一个bitmap
对象指定唯一一个key
,这样子就可以把图片放入内存中,使用的时候只要 :
Bitmap bitmap = (Bitmap)memoryCache.get("test");
ok,关于LruCache
的简单用法介绍就是以上这些,更多的用法请移步官网查看相关文档
DiskLruCache
这个类是专门用于硬盘缓存的.不过你首先得知道这个类并不包含在Android SDK
里面,所以如果你需要使用这个类,那么你就得去下载java
文件放入到你的工程中.如果你是使用Android Studio
,那么只要把这个类拷贝到你的工程目录下就可以了.对于这个缓存类,一般我们会把缓存内容放在/data/data/你的包名/cache
或者/sdcard/Android/data/你的包名/cache
文件夹中.
DiskLruCache
这个类的对象是不能使用new
创建的,而是使用open
函数.
DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
- 第一个参数指定缓存路径
- 第二个指版本号
- 第三个参数指定同一个
key
可以指定多少缓存文件,一般填就够了 - 最后一个参数指定了最大缓存容量.
一般而言,我们为了考虑到手机是否有SD
卡而使用不同的缓存路径,在有SD
卡的情况下使用/sdcard/Android/data/你的包名/cache
,没有SD
卡使用/data/data/你的包名/cache
private File getDiskCacheDir(Context context, String name) { boolean externalStorageAvailable = Environment.getExternalStorageState() .equals(Environment.MEDIA_MOUNTED); String cachePath; if (externalStorageAvailable) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + name);}
使用上面的函数就可以判断我们应该哪个缓存路径,注意这里的name
参数,这里会在cache
文件夹中生成一个名字为name
的文件夹,我们一般存放不同类型文件会分别设定一个文件夹,比如放置图片缓存就建立一个bitmap
的文件夹,网页数据可能就建立一个web
的文件夹.
写入缓存
写入缓存我们使用DiskLruCache.Editor
这个类完成,但是这个类也不能new
出来,而是使用edit
函数获得
public Editor edit(String key)
可以看到edit
接收一个key
获取缓存.一般,比如对应一张图片,我们会使用他的URL
地址作为key
,但是直接使用URL
作为key
可能包含非法字符,所以一般我们会对URL
进行MD5
编码之后使用.
private String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (1 == hex.length()) { sb.append('0'); } sb.append(hex); } return sb.toString();}//url ---> MD5private String hashKeyForUrl(String url) { String cacheKey; try { MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(url.getBytes()); cacheKey = bytesToHexString(digest.digest()); } catch (Exception e) { cacheKey = String.valueOf(url.hashCode()); } return cacheKey;}
那么,现在我们可以把一个URL
转换成MD5
编码,key
我们搞定了,但是我们要写入的缓存内容呢?通常我们会开启一个子线程,先把图片下载到本地,然后通过edit
提交.
private boolean downloadToStream(String uriString, OutputStream outputStream) { HttpURLConnection conn = null; BufferedOutputStream os = null; BufferedInputStream is = null; try { URL url = new URL(uriString); conn = (HttpURLConnection) url.openConnection(); is = new BufferedInputStream(conn.getInputStream(), IO_BUFFER_SIZE); os = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE); int b; while ((b = is.read()) != -1) { os.write(b); } return true; } catch (Exception e) { e.printStackTrace(); } finally { if (conn != null) { conn.disconnect(); } try { is.close(); os.close(); } catch (IOException e) { e.printStackTrace(); } } return false;}
如上,根据URL
,我们把图片下载保存到了outputStream
流中,可是这个怎么跟edit
关联上呢
DiskLruCache.Editor editor = diskLruCache.edit(key);if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); if (downloadToStream(uri, outputStream)) { editor.commit(); } else { editor.abort(); }
这样子就清楚了吧,不过注意,我们在使用open
函数的时候第三个参数写的是1,所以这里newOutputStream
要写0就可以了.
完整代码 :
String key = hashKeyFormUrl(uri);try { DiskLruCache.Editor editor = diskLruCache.edit(key); if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); if (downloadToStream(uri, outputStream)) { editor.commit(); } else { editor.abort(); } diskLruCache.flush(); }} catch (IOException e) { e.printStackTrace();}private boolean downloadToStream(String uriString, OutputStream outputStream) { HttpURLConnection conn = null; BufferedOutputStream os = null; BufferedInputStream is = null; try { URL url = new URL(uriString); conn = (HttpURLConnection) url.openConnection(); is = new BufferedInputStream(conn.getInputStream(), IO_BUFFER_SIZE); os = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE); int b; while ((b = is.read()) != -1) { os.write(b); } return true; } catch (Exception e) { e.printStackTrace(); } finally { if (conn != null) { conn.disconnect(); } try { is.close(); os.close(); } catch (IOException e) { e.printStackTrace(); } } return false;}
读取缓存
写入之后读取缓存也不是一件难事,同样,我们还是得先把URL
转换成MD5
编码,然后去获得缓存
String key = hashKeyFormUrl(uri);try { DiskLruCache.Snapshot snapshot = diskLruCache.get(key); if (snapshot != null) { InputStream fs = (InputStream) snapshot.getInputStream(0); Bitmap bitmap = BitmapFactory.decodeStream(fs); }} catch (Exception e) { e.printStackTrace();}
以上,就是关于Android
中内存缓存和硬盘缓存的内容.
- Android图片缓存技术
- Android WebView缓存技术
- Android图片缓存技术
- android离线缓存技术
- Android缓存技术
- android 缓存技术lrucache
- Android----图片缓存技术
- android 自定义view 缓存技术
- android 图片加载+缓存技术
- Android中的LruCache缓存技术
- Android技术——缓存技术
- Android 图片缓存之内存缓存技术LruCache,软引用
- Android 图片缓存之内存缓存技术LruCache,软引用
- Android 图片缓存之内存缓存技术LruCache,软引用
- 【Android】【缓存】Andrid高效显示Bitmap( 使用缓存技术)
- Android 图片缓存之内存缓存技术LruCache,软引用
- Android 图片缓存之内存缓存技术LruCache,软引用
- android图片缓存之内存缓存技术LruCache,软引用
- 算法-删数
- python的安装 在win上使用py
- 反射基础
- 查看linux性能信息cpu-内存-硬盘-网卡
- CSS之派生选择器(上下文选择器)
- Android缓存技术
- 数据结构实验之栈二:一般算术表达式转换成后缀式
- javascript渲染单页效率简述
- 多线程join的问题
- 贪心算法-最优装载
- android23种设计模式
- Unity3D仿仙剑对话系统开发
- 七种经典排序算法最全攻略
- Androidstudio下代码混淆