Android 使用LruCache和DiskLruCache建立图片加载库

        目前第三方的图片加载库很多,例如:universal-image-loader,Volley等,今天我们来写一个简单的图片加载库实现图片网络下载缓存。

        首先先了解一下图片加载用什么方式,通常我们从网络加载图片的时候希望加载的图片优先从本地缓存获取,本地没有就从网络下载再缓存到本地,这样可以减少网络访问的开销和提高图片加载的速度,从而增加用户体验。

        本地的缓存资源可以保存在内存和本地文件中,那么图片的加载流程优先级由高到低是:从内存中获取--从本地缓存文件中获取--从网络获取。

        我们内存缓存使用的是 LruCache,文件缓存使用的是DiskLruCache 或者 File 类。

        注意:以前也有使用软引用和弱引用实现图片缓存,但这种方式从API 9 开始起不了作用了。垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。

一、LruCache

        这个类是android 3.1 提供的,之前的旧版本需要使用android-support-v4 支持库才能使用。LruCache使用一个LinkedHashMap简单的实现内存的缓存,没有软引用,都是强引用。

下面看看LruCache怎样使用

(1)新建LruCache对象

mMemoryCache = new LruCache<String, Bitmap>(maxCacheSize) {
    // 必须重写此方法,来测量Bitmap的大小 
    @Override 
    protected int sizeOf(String key, Bitmap value) { 
        return value.getRowBytes() * value.getHeight(); 
    }
};

 LruCache的构造方法传入的参数是指定缓存的大小,如果添加的数据大于设置的最大值,就删除最先缓存的数据来调整内存。重写的方法sizeof是计算图片的大小。 

(2)添加图片缓存

//添加Bitmap到内存缓存  
mMemoryCache.put(key, bitmap); 

key的值用于取出对应的图片缓存用的。

(3)获取图片缓存

//从内存缓存中获取一个Bitmap  
mMemoryCache.get(key); 

LruCache的方法不多,用的最多的是添加和获取的方法了,总的来说LruCache 的使用还是比较简单的。

二、DiskLruCache

        DiskLruCache 硬盘缓存,DiskLruCache 并不在 Android API 中,我们需要在网上下载源码文件,把源码文件放到我们的工程里,记得改源码文件的包路径。

添加DiskLruCache 类到工程里面之后,看看它是怎么用的

(1)创建 DiskLruCache

DiskLruCache的创建需要调用它的静态方法open

public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize);
该方法的参数有4个:

directory  ---- 数据的缓存路径

appVersion ---- 当前应用程序的版本号

valueCount ---- 指定同一个key可以对应多少个缓存文件,基本都是传1

maxSize ---- 最多可以缓存多少字节的数据


例子:

/**
     * 初始化 DiskLruCache
     */
    private void initDiskLruCache() {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            try {
                diskLruCache = DiskLruCache.open(new File(getCacheStoragePath()), info.versionCode, 1,
                        config.disCacheSize);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }

(2)获取缓存文件资源

DiskLruCache.Snapshot snapShot = diskLruCache.get(subUrl);
if (snapShot != null) { 
     FileInputStream fileInputStream = (FileInputStream) snapShot.getInputStream(0);
     // 从流中转成Bitmap对象
     bitmap = BitmapFactory.decodeStream(fileInputStream); 
   ...
} else { 
     Log.i("load", "手机存储中没有");
}

 

(3)保存缓存文件

先获取 DiskLruCache.Editor 对象
DiskLruCache.Editor editor = diskLruCache.edit(key);//参数 key 是缓存文件的文件名
if (editor != null) {
    //从Editor 获取缓存的输出流
    OutputStream outputStream = editor.newOutputStream(0);
    //把数据保存成文件
    bitmap.compress(config.compressFormat, config.imageQuality, outputStream);
    //commit 提交
    editor.commit(); 
    ...
}  

其它的操作:
diskLruCache.delete();  删除全部缓存文件
diskLruCache.flush();
diskLruCache.close(); 关闭缓存
diskLruCache.remove(key);  移除key对应的缓存
diskLruCache.size() 缓存的大小
diskLruCache.getDirectory() 缓存目录
diskLruCache.isClosed() 缓存是否关闭

三、设计图片加载库

设计的目标:

(1)加载流程 :从内存中获取--从本地缓存文件中获取--从网络获取

(2)线程池

(3)LruCache 负责内存缓存,DiskLruCache 负责硬盘缓存。


具体的源码:

https://github.com/StarsAaron/Imageloder.git



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星点点-

请我喝杯咖啡呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值