Android高效ImageLoader的实现

在android开发过程图片加载和显示基本上是每个项目中都会包含的功能,这就导致每个项目里面ImageLoader是标配。当然我们在使用的过程中有很多牛逼的(性能好,使用简单方便)开源框架可供挑选。但是如果自己手动实现一个高效的ImageLoader那给自己的技术树里面又添加了一个靓丽的枝干。ok,接下来我们一起来分析和探讨一下高效ImageLoder的实现。

一般来说,优秀的ImageLoader都具有以下几个共性:

  • 图片的同步加载
  • 图片的异步加载
  • 图片按需要压缩
  • 内存缓存
  • 磁盘缓存
  • 网络拉取
  • 使用方便简单
  • 性能好

虽然我们可能做不到优秀,但是我们也得往这个目标和方向上使劲。所以接下来的实现中,我们也会尽力去做到这些。

  • 前两年很多同行使用软引用和弱引用来实现图片的多级缓存,但是现在使用软引用和弱引用已经变得不再可靠,它主要存在以下几点弊端和风险 因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。

  • 另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,这就有潜在的风险造成应用程序的内存溢出并崩。

基于这些问题和风险,我们使用在3.0以后被Android引入的LruCache来进行图片内存缓存,(这个类是3.1版本中提供的,如果你是在更早的Android版本中开发,则需要导入android-support-v4的jar包)

LruCache在处理图片释放时使用的原则是最久未使用原则,即:当LruCache内存储的图片总大小大于指定内存时,自动释放未使用时长最久的图片。ok,内存缓存就它了。

我们说过优秀ImageLoader还应该包含磁盘缓存,那么我们在磁盘缓存中我们可以考虑用最基本的文件存取来实现,因为一般来说,我们的磁盘缓存在我看来就是对我们的数据进行一下备份,方便需要的时候获取,不太需要多么优秀的算法来控制它们。但是现在业内的普遍做法是使用DisckLruCache来做磁盘缓存。好吧,虽然笔者不太清楚这样做的原理,但是我们照猫画虎,也就用这个吧。毕竟我们是奔着优秀去的,业内的一些反响比较好的图片加载框架都用的它,肯定是有使用的价值所在。

ok,分析完基本的技术选型,我们开始进入框架编写的正题。

我们先从调用开始讲起,我们这边提供两种调用的方式:同步调用和异步异步调用,我们把这两个方法定义如下。

    /**
     * 图片异步加载
     */
    public void bind(String resource,ImageView imageView,int reqWidth,int reqHeight){

    }

    /**
     *图片同步加载
     */
    public Bitmap load(String resource,int reqWidth,int reqHeight){
        Bitmap bitmap = null;
        return bitmap;
    }

两种加载方式的实现,我们接下来一步一步地写。图片使用和加载的效率有高到低的顺序为:内存缓存 >SD卡缓存>网络请求

ok,接下来我们对内存缓存和SD卡缓存进行初始化配置。在这里我们提供一个ImgLoaderConfig来设置相关配置,这个主要包括以下几个属性(需要的话再进行进一步扩展):

    /**
     * 内存缓存大小
     */
    private int memoryCacheSize;
    /**
     * SD卡缓存大小
     */
    private long diskCacheSize;
    /**
     * SD卡缓存路径
     */
    private String diskCachePath;

好了,有个这个配置类,我们可以编写我们的初始化配置方法了:

/**
     * 初始化方法
     *
     * @param config  图片加载框架相关配置
     * @param context 上下文
     */
    public void init(ImgLoaderConfig config, Context context) {
        if (null == context) {
            throw new IllegalArgumentException("the context could not is null");
        }

        if (config.getMemoryCacheSize() <= 0) {
            int maxMemory = (int) Runtime.getRuntime().maxMemory() / 1024;
            memoryCacheSize = maxMemory / 8;
        } else {
            memoryCacheSize = config.getMemoryCacheSize();
        }

        if (config.getDiskCacheSize() <= 0) {
            diskCacheSize = DISK_CACHE_SIZE;
        } else {
            diskCacheSize = config.getDiskCacheSize();
        }

        mMemoryCache = 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值