UniversalImageLoader源码解读05-磁盘缓存

      磁盘缓存对于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做了一层包装

 到此磁盘缓存就算完成了,其实很简单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值