您的位置:首页 > 其它

DiskLruCache本地缓存图片技术精炼详解

2018-04-09 21:18 549 查看

一、前期基础知识储备

上一篇文章《LruCache内存缓存图片技术精炼详解》中,笔者分析了利用LruCache类实现图片的内存缓存,在应用程序中,如果已经联网加载好了图片,那么把图片保存到内存中,下一次加载就会十分迅速。但是,内存缓存技术,也有缺点,如果图片从内存里被移除了的话,那么下一次加载仍然是要从网络中获取,那么有没有什么办法可以做到一个“中间状态”,既不用每次从网络加载,又不用担心内存不足的问题。于是,Google又提供了一套硬盘缓存的解决方案:DiskLruCache,利用这类来实现本地的缓存,所以在下载完图片之后,既可以先保存在内存中,又可以保存在本地SD卡中,那么下一次加载这张图片就会十分迅速。
(1)DiskLruCache应用程序实践
每次我们打开一个图文app时,比如浏览器,都需要从网络中加载大量的图片,然后我们关闭这个应用程序,断开网络连接,下次再打开这个应用程序时,我们会发现上次加载的内容依旧保留着,这种应用程序都是运用了本地缓存的技术,非常常见。
(2)DiskLruCache本地缓存默认路径
通常情况下多数应用程序都会将缓存的位置选择为/sdcard/Android/data/<application package>/cache 这个路径,但DiskLruCache本身并没有限制存储的位置,我们也可以自己设置。

二、上代码,具体实现

由于DiskLruCache并不是由Google官方编写的,所以这个类并没有被包含在Android API当中,我们需要将这个类从网上下载下来,然后手动添加到项目当中。DiskLruCache的源码在Google Source上:GoogleSource
先实现本地存储文件过程
(1)新建DiskLruCache对象//DiskLruCache实例,它的构造方法是私有的,所以我们需要通过它提供的open方法来生成。
try {
mDiskLruCache = DiskLruCache.open(getDiskCacheDir(MyApplication.getContext(),CACHE_FOLDER_NAME),
getAppVersion(MyApplication.getContext()) , 1, DISKMAXSIZE);
} catch (IOException e) {
e.printStackTrace();
}open()方法接收四个参数,第一个参数指定的是数据的缓存地址,第二个参数指定当前应用程序的版本号,第三个参数指定同一个key可以对应多少个缓存文件,一般都是传1,第四个参数指定最多可以缓存多少字节的数据。
获取应用程序的版本号,代码如下:public int getAppVersion(Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return info.versionCode;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return 1;
} (2)开启新线程
文件的读写都是耗时操作,这里我们要开启支线程进行文件的读取操作
(3)创建DiskLruCache.Editor对象
    
try{
String imageUrl = "http://xxx";
String key = hashKeyForDisk(imageUrl);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (downloadUrlToStream(imageUrl, outputStream)) {
editor.commit();
}
} catch (IOException e) {
e.printStackTrace();
}

创建DiskLruCache.Editor对象,调用它的newOutputStream()方法来创建一个输出流,然后把它传入到downloadUrlToStream()中就能实现下载并写入缓存的功能。
注:newOutputStream()方法接收一个index参数,由于前面在设置valueC
a66d
ount的时候指定的是1,所以这里index传0就可以了。在写入操作执行完之后,我们还需要调用一下commit()方法进行提交才能使写入生效。
完整的本地存储代码如下:new Thread(new Runnable() {
@Override
public void run() {
try {
String imageUrl = "http://xxx";
String key = hashKeyForDisk(imageUrl);
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (downloadUrlToStream(imageUrl, outputStream)) {
editor.commit();
} else {
editor.abort();
}
}
mDiskLruCache.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();——————————————————我是分隔线——————————————————
接着来实现本地文件的读取过程
其实过程和本地存储过程很相似,就是读取的时候调用的是get()方法,存储的时候调用的是edit()方法。try{
String imageUrl = "http://xxx";
String key = hashKeyForDisk(imageUrl);
DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
if (snapShot != null) {
nputStream inputStream = snapShot.getInputStream(0);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
mImage.setImageBitmap(bitmap);
}
} catch (IOException e) {
e.printStackTrace();
}总结:DiskLruCache是现在非常流行的用于实现本地图片缓存的技术,联网,是现在手机最大的特点之一,而联网之后,又会产生许多的数据,这些数据,如果每次打开都从网络重新获取一遍,对于用户本身是一种负担,因为读取网络内容的速度没有那么迅速,另外就是产生的流量消耗,也不可小觑。所以同时使用DiskLruCache本地缓存技术+LruCache内存缓存技术是现在应用程序非常常见的缓存技术。如果在加上一些非常流行的网络框架,比如Volley、OkHttp,那么请求网络数据,加载网络数据就会变得十分便捷,这就是现在很多的一个概念——“三级缓存”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: