您的位置:首页 > 其它

UniversalImageLoader源码解读05-磁盘缓存

2016-05-11 19:28 381 查看
磁盘缓存对于UniversalImageloader也是至关重要的,我们总不能每次显示图片都要去网络获取吧,即使有内存缓存,当重启手机,或者内存缓存被清理,那么还是要从网络上去获取,这就是磁盘缓存的意义。

框架中对于磁盘缓存的抽象是DiskCache ,我们先看一下定义:

public interface DiskCache {
/**
* 返回缓存文件夹
*/
File getDirectory();

/**
* 根据图片Uri从缓存中取出图片
*/
File get(String imageUri);

/**
* 图片保存到磁盘缓存
*/
boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException;

/**
* 图片保存到磁盘缓存
*/
boolean save(String imageUri, Bitmap bitmap) throws IOException;

/**
* 从磁盘缓存删除图片
*/
boolean remove(String imageUri);

/** 关闭磁盘缓存,并清理资源 */
void close();

/** 清空图片磁盘缓存 */
void clear();
}


BaseDiskCache 为我们提供了默认实现,开发者需要继承它,它里面有一点需要注点意的,其他代码很简单,只不过作为基类为abstract ,这也意味着框架强制你继承这个类,虽然基类实现了所有的方法,自己看源码吧,很简单

protected final File cacheDir;
protected final File reserveCacheDir;


框架指定了两个缓存文件夹,当cacheDir不可用时,使用reserveCacheDir ,从名字就可以看出来 :reserve 保留的,备用的

UnlimitedDiskCache 直接实现BaseDiskCache,这里不讲了

LimitedAgeDiskCache :Cache which deletes files which were loaded more than defined time. Cache size is unlimited. 这是源码注释,意思是,超过某个时刻,就会被删除,我们看一下具体实现,看注释吧,不解释,很简单

public class LimitedAgeDiskCache extends BaseDiskCache {

private final long maxFileAge;//毫秒为单位

//保存每个图片文件被缓存到磁盘上的事件
private final Map<File, Long> loadingDates = Collections.synchronizedMap(new HashMap<File, Long>());

public LimitedAgeDiskCache(File cacheDir, long maxAge) {
this(cacheDir, null, DefaultConfigurationFactory.createFileNameGenerator(), maxAge);
}

public LimitedAgeDiskCache(File cacheDir, File reserveCacheDir, long maxAge) {
this(cacheDir, reserveCacheDir, DefaultConfigurationFactory.createFileNameGenerator(), maxAge);
}

public LimitedAgeDiskCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator, long maxAge) {
super(cacheDir, reserveCacheDir, fileNameGenerator);
this.maxFileAge = maxAge * 1000; // to milliseconds
}

/**
* 和一般的磁盘缓存一下,使用懒删除,就是访问的时候才去检查是否过期
*/
@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();//图片的last modified time
} else {
cached = true;
}

if (System.currentTimeMillis() - loadingDate > maxFileAge) {
file.delete();//超过时限就删除
loadingDates.remove(file);
} else if (!cached) {
loadingDates.put(file, loadingDate);
}
}
return file;
}

@Override
public boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException {
boolean saved = super.save(imageUri, imageStream, listener);
rememberUsage(imageUri);
return saved;
}

@Override
public boolean save(String imageUri, Bitmap bitmap) throws IOException {
boolean saved = super.save(imageUri, bitmap);
rememberUsage(imageUri);
return saved;
}

@Override
public boolean remove(String imageUri) {
loadingDates.remove(getFile(imageUri));
return super.remove(imageUri);
}

@Override
public void clear() {
super.clear();
loadingDates.clear();
}

/**
* 对最后的访问时间做了一个缓存,这只是为了方便而已
*/
private void rememberUsage(String imageUri) {
File file = getFile(imageUri);
long currentTime = System.currentTimeMillis();
file.setLastModified(currentTime);
loadingDates.put(file, currentTime);
}
}


还有一个包com.nostra13.universalimageloader.cache.disc.impl.ext , 这个包也是实现了一种磁盘缓存叫LruDiskCache, 它把Android源码直接拷贝了进来, DiskLruCache依赖StrictLineReader 和Util, 当然,框架的LruDiskCache对DiskLruCache做了一层包装

到此磁盘缓存就算完成了,其实很简单
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: