当前位置: 移动技术网 > IT编程>移动开发>Android > Android开发之ImageLoader本地缓存

Android开发之ImageLoader本地缓存

2019年07月24日  | 移动技术网IT编程  | 我要评论

赤城流浪的蛤蟆,韩寒妻子再生子,田扑君

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网