Android开发之ImageLoader本地缓存

 更新时间:2016年01月13日 10:31:12   投稿:mrr  
ImageLoader是一个图片缓存的开源库,提供了强大的图片缓存机制,很多开发者都在使用,今天给大家介绍Android开发之ImageLoader本地缓存。对imageloader本地缓存相关知识感兴趣的朋友一起学习吧

ImageLoader是一个图片缓存的开源库,提供了强大的图片缓存机制,很多开发者都在使用,今天给大家介绍Android开发之ImageLoader本地缓存,具体内容如下所示:

本地缓存在缓存文件时对文件名称的修改提供了两种方式,每一种方式对应了一个Java类

1) HashCodeFileNameGenerator ,该类负责获取文件名称的hashcode然后转换成字符串。

2) Md5FileNameGenerator ,该类把源文件的名称同过md5加密后保存。

两个类都继承了FileNameGenerator接口

在DefaultConfigurationFactory类中提供了一个工厂方法createFileNameGenerator,该方法返回了一个默认的FileNameGenerator对象:HashCodeFileNameGenerator.

public static FileNameGenerator createFileNameGenerator() { 
return new HashCodeFileNameGenerator(); 
}

实现

首先定义了DiscCacheAware接口,该接口提供了如下方法

File getFileDectory() 返回磁盘缓存的根目录
File get(String imageUri) 根据uri从缓存中获取图片
boolean save(String imageUri,InputStream iamgeStream,IoUtils.CopyListener listener) 把图片保存在磁盘缓存上
boolean save(String imageUri,Bitmap bitmap) 保存bitmap对象到磁盘缓存上
boolean remove(imageUri) 根据imageUri删除文件
void close() 关闭磁盘缓存,释放资源
void clear() 清空磁盘缓存

然后定义了另外一个没方法的接口DiskCache,该接口只是简单的继承了DiscCacheAware接口。

BaseDiscCache实现了DiskCache,该类是个抽象类,该类定义了磁盘缓冲区的以下的属性

1) 默认的缓存大小为32k

2) 默认压缩后的图片格式为PNG(作为Bitmap的compress方法的第一个参数)

3) 默认压缩后图片显示的质量为100,也就是压缩率为0,不进行压缩(作为compress的第二个参数)

提供了修改压缩图片格式和压缩率以及修改缓存大小的set方法。同时该类还封装了以下三个属性

protected final File cacheDir;//缓存文件的保存Directory
protected final File reserveCacheDir;//后备缓存的Diectory,当cacheDir不存在的情况下就是用reserveCahceDir后备缓存
protected final FileNameGenerator fileNameGenerator;//文件名名称生成器

构造函数

public BaseDiscCache(File cacheDir) {
this(cacheDir, null);
}
public BaseDiscCache(File cacheDir, File reserveCacheDir) {
this(cacheDir, reserveCacheDir, DefaultConfigurationFactory.createFileNameGenerator());
}
public BaseDiscCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator) {
if (cacheDir == null) {
throw new IllegalArgumentException("cacheDir" + ERROR_ARG_NULL);
}
if (fileNameGenerator == null) {
throw new IllegalArgumentException("fileNameGenerator" + ERROR_ARG_NULL);
}
this.cacheDir = cacheDir;
this.reserveCacheDir = reserveCacheDir;
this.fileNameGenerator = fileNameGenerator;
}

1) 只有一个参数的构造函数只初始化了cacheDir,没有用到后备缓存,且是以HashCodeFileNameGenerator来生成目标文件的文件名。

2) 两个参数的构造器除了cacheDir和HashCodefileNameGenerator外,也可以初始化后备缓存

3) 三个参数的构造器要求必须初始化cacheDir并且必须初始化filenNameGenerator否则就报异常

get(String imageUri)

protected File getFile(String imageUri) { 
String fileName = fileNameGenerator.generate(imageUri); 
File dir = cacheDir; 
if (!cacheDir.exists() && !cacheDir.mkdirs()) { 
if (reserveCacheDir != null && (reserveCacheDir.exists() || reserveCacheDir.mkdirs())) { 
dir = reserveCacheDir; 
} 
} 
return new File(dir, fileName); 
}

save(String imageUri, Bitmap bitmap)

public boolean save(String imageUri, Bitmap bitmap) throws IOException { 
//获取imageUri的File对象,该对象封装了缓存路径和图片保存后的名称 
File imageFile = getFile(imageUri); 
//获取临时保存文件的tmpFile对象 
File tmpFile = new File(imageFile.getAbsolutePath() + TEMP_IMAGE_POSTFIX); 
OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile), bufferSize); 
boolean savedSuccessfully = false; 
try { 
//调用compress把bitMap压缩到tempFile中 
savedSuccessfully = bitmap.compress(compressFormat, compressQuality, os); 
} finally { 
IoUtils.closeSilently(os); 
//如果保存成功并且tempFile的文件没有成功移动到imageFile的话,就删除temFile 
if (savedSuccessfully && !tmpFile.renameTo(imageFile)) { 
savedSuccessfully = false; 
} 
if (!savedSuccessfully) { 
tmpFile.delete(); 
} 
} 
//对bitmap进行垃圾回收 
bitmap.recycle(); 
return savedSuccessfully; 
}

BaseDiscCache有两个扩展类,一个是 不限制缓存大小的 UnlimitedDiscCache 和 限制缓存时间的LimitedAgeDiscCache, 其中UnlimitedDiscCache很简单它只是简单的继承了BaseDiscCache并未对BaseDiscCache做任何扩展。

LimitedAgeDiscCache 该类实现了在缓存中删除被加载超过规定时间的文件: 满足以下条件的时候就从缓存中删除文件:系统当前时间-文件的最新修改时间 > maxFileAge

LimitedAgeDiscCache

该类提供了两个属性:

1. maxFileAge(long)设置加载的超时的最大时间,改时间在构造器冲初始化,一经初始化就不能改变(设定文件存活的最长时间,当超过这个值,就删除该文件)

2. loadingDates (Map<File,long>),该属性是一个map类型的对象,key保存的要缓存的图片文件,而value保存的是调用save方法是系统的当前时间,具体向loadingDates填充数据是在下面的rememberUsage方法中实现的,该方法在类中两个save方法中调用,首先调用父类的save方法,然后在调用此方法

private void rememberUsage(String imageUri) { 
File file = getFile(imageUri); 
long currentTime = System.currentTimeMillis(); 
file.setLastModified(currentTime); 
loadingDates.put(file, currentTime); 
}

从缓存中获取数据的方法为get(String imageUri)该类是重写BaseDiscDache方法,该方法从loadingDates中获取imageUri所代表的图片的最新更新时间loadingDate, 然后拿当前时间和loadingDate做差,如果差值大于maxFileAge也就是说查过了加载的最大时间,就删除该imageUri所代表的file,并从loadingDates中的数据,当然如果map中没有imageUri就不会涉及到超时的问题,此时就把image放入map中去 ,具体的实现如下

@Override 
public File get(String imageUri) { 
File file = super.get(imageUri); 
if (file != null && file.exists()) { 
boolean cached; 
Long loadingDate = loadingDates.get(file); 
if (loadingDate == null) { 
cached = false; 
loadingDate = file.lastModified(); 
} else { 
cached = true; 
} 
if (System.currentTimeMillis() - loadingDate > maxFileAge) { 
file.delete(); 
loadingDates.remove(file); 
} else if (!cached) { 
loadingDates.put(file, loadingDate); 
} 
} 
return file; 
}

相关文章

  • Android Mms之:深入MMS支持

    Android Mms之:深入MMS支持

    本篇文章是对Android中MMS支持进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 获取android4.0版本sdcard路径示例

    获取android4.0版本sdcard路径示例

    自从android4.0开始,谷歌为没有内存卡的手机模拟了一个SD卡,占用了原来的SD卡路径,并为真实的sd卡挂载到该目录的子目录,由于所挂载的目录并没有官方规范,所以命名会不同,只能通过搜索,下面是获取android4.0版本sdcard路径示例
    2014-03-03
  • Android实现PDF预览打印功能

    Android实现PDF预览打印功能

    这篇文章主要为大家详细介绍了Android实现PDF预览打印功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Android中的Coroutine协程原理解析

    Android中的Coroutine协程原理解析

    这篇文章主要介绍了Android中的Coroutine协程原理解析,本文将会围绕挂起与恢复彻底剖析协程的实现原理,包括Kotlin函数基础知识复习,关于函数的个人经验总结,需要的朋友可以参考下
    2022-03-03
  • Android开发之TimePicker控件用法实例详解

    Android开发之TimePicker控件用法实例详解

    这篇文章主要介绍了Android开发之TimePicker控件用法,结合实例形式详细分析了Android项目的建立及TimePicker控件的具体使用技巧,需要的朋友可以参考下
    2016-02-02
  • Android常用三方库混淆规则整理(小结)

    Android常用三方库混淆规则整理(小结)

    这篇文章主要介绍了Android常用三方库混淆规则整理(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • Android 使用Vitamio打造自己的万能播放器(1)——准备

    Android 使用Vitamio打造自己的万能播放器(1)——准备

    本文主要介绍Android Vitamio,在Android开发视频播放器的时候,大家经常会遇到系统版本和不同的Android手机不同导致开发的软件不能完美适用,这里给大家介绍个播放器插件可以适应所有Android设备
    2016-07-07
  • 详解Android Ashmem匿名共享内存

    详解Android Ashmem匿名共享内存

    这篇文章主要介绍了Android Ashmem匿名共享内存的相关资料,帮助大家更好的理解和学习使用Android开发,感兴趣的朋友可以了解下
    2021-04-04
  • Android编程之手机壁纸WallPaper设置方法示例

    Android编程之手机壁纸WallPaper设置方法示例

    这篇文章主要介绍了Android编程之手机壁纸WallPaper设置方法,结合实例形式分析了Android手机壁纸WallPaper的相关设置与使用技巧,需要的朋友可以参考下
    2017-08-08
  • Android网络开发中GET与POST请求详解

    Android网络开发中GET与POST请求详解

    这篇文章主要介绍了android实现网络请求的get和post请求的简单封装与使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2022-12-12

最新评论