Android开发之ImageLoader本地缓存_Android

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;
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索imageloader本地缓存
imageloader缓存
imageloader本地缓存、imageloader清除缓存、imageloader三级缓存、imageloader 缓存机制、imageloader缓存图片,以便于您获取更多的相关知识。

时间: 2024-10-09 04:14:53

Android开发之ImageLoader本地缓存_Android的相关文章

Android开发之ImageLoader本地缓存

ImageLoader是一个图片缓存的开源库,提供了强大的图片缓存机制,很多开发者都在使用,今天给大家介绍Android开发之ImageLoader本地缓存,具体内容如下所示: 本地缓存在缓存文件时对文件名称的修改提供了两种方式,每一种方式对应了一个Java类 1) HashCodeFileNameGenerator ,该类负责获取文件名称的hashcode然后转换成字符串. 2) Md5FileNameGenerator ,该类把源文件的名称同过md5加密后保存. 两个类都继承了FileNam

Android开发之ImageLoader使用详解_Android

先给大家展示效果图,看看是大家想要的效果吗,如果还满意,请参考以下代码: 前言 UniversalImageLoader是用于加载图片的一个开源项目,在其项目介绍中是这么写的, •支持多线程图片加载 •提供丰富的细节配置,比如线程池大小,HTPP请求项,内存和磁盘缓存,图片显示时的参数配置等等: •提供双缓存 •支持加载过程的监听: •提供图片的个性化显示配置接口: •Widget支持(这个,个人觉得没必要写进来,不过尊重原文) 其他类似的项目也有很多,但这个作为github上著名的开源项目被广

Android开发之ImageLoader使用详解

先给大家展示效果图,看看是大家想要的效果吗,如果还满意,请参考以下代码: 前言 UniversalImageLoader是用于加载图片的一个开源项目,在其项目介绍中是这么写的, •支持多线程图片加载 •提供丰富的细节配置,比如线程池大小,HTPP请求项,内存和磁盘缓存,图片显示时的参数配置等等: •提供双缓存 •支持加载过程的监听: •提供图片的个性化显示配置接口: •Widget支持(这个,个人觉得没必要写进来,不过尊重原文) 其他类似的项目也有很多,但这个作为github上著名的开源项目被广

Android开发之ViewSwitcher用法实例_Android

本文实例讲述了Android开发之ViewSwitcher用法.分享给大家供大家参考,具体如下: android.widget.ViewSwitcher是ViewAnimator的子类,用于在两个View之间切换,但每次只能显示一个View. ViewSwitcher的addView函数的代码如下: /** * {@inheritDoc} * * @throws IllegalStateException if this switcher already contains two childre

Android开发之Service用法实例_Android

本文实例讲述了Android开发之Service用法.分享给大家供大家参考.具体分析如下: Service是一个生命周期较长而且没有界面的程序. 下面通过一个播放mp3的例子来学习. 先看MainActivity.java package com.example.servicetest; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view

学习Android开发之RecyclerView使用初探_Android

在进行一些MaterialDesign规范开发的时候,比如之前说到的CoordinateLayout实现的向上折叠效果的时候,如果依然使用ListView,那么这种效果是做不出来的,因为ListView不兼容这个控件,而替代它的就是RecyclerView. 和ListView的区别:  ①RecyclerView只关心item的重用和缓存  ②RecyclerView不关心item的分隔风格(交给ItemDecoration)  ③RecyclerView不关心item的动画(交给ItemAn

Android开发之Wifi基础教程_Android

本文实例讲述了Android开发Wifi的基础知识.分享给大家供大家参考.具体如下: Android提供了WifiManager这个类,通过这个类可以进行wifi相关的各种操作. 通过 wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE) 可获取该类的实例. 1. 获取wifi开启状态 (只要手机的wifi打开了,即认为是开启状态,而与是否连接了某个wifi无关): boolean isOpen = wifiMana

Android开发之Activity详解_Android

[Activity] 一个Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,例如拨号.拍照.发送email.看地图.每一个activity被给予一个窗口,在上面可以绘制用户接口.窗口通常充满屏幕,但也可以小于屏幕而浮于其它窗口之上. 一个应用程序通常由多个activities组成,他们通常是松耦合关系.通常,一个应用程序中的activity被指定为"main"activity,当第一次启动应用程序的时候呈现给用户的那个activity.每一个activ

Android开发之RecyclerView控件_Android

现阶段,我们创建了最简单的Android项目,现在在此公布github链接https://github.com/neuyu/android-best-practices,希望大家多多支持. 因为之前谈到过包结构的定义,我选择第一种方式,按照Android特性定义,所以你的包结构应该是这样的: RecyclerView 在MainActivity中,我们需要用到RecyclerView这一新控件,那么如何引用,如何使用它呢?在gradle文件中添加库依赖: compile 'com.android