Android 平滑图片加载和缓存库 Glide 使用详解

在图片加载库烂大街的今天,选择一个适合自己使用的图片加载库已经成为了每一个Android开发者的必经之路。现在市面上知名的图片加载库有UIL,Picasso,Volley ImageLoader,Fresco以及我们今天的主角Glide。它们各有千秋,不能评定谁一定比谁好,只能说哪一个更适合你。

我的理解

下面我来谈一下个人对这些图片加载库的理解,如有错误,还望指教。

Universal Image Loader:一个强大的图片加载库,包含各种各样的配置,最老牌,使用也最广泛。

Picasso: Square出品,必属精品。和OKHttp搭配起来更配呦!

Volley ImageLoader:Google官方出品,可惜不能加载本地图片~

Fresco:Facebook出的,天生骄傲!不是一般的强大。

Glide:Google推荐的图片加载库,专注于流畅的滚动。

更多详情请看stackoverflow上这个问题

初试Glide

下面进入今天的主题,相信之前很多同学都看到过这篇介绍Glide的文章,中文版在这里。文中从各个方面介绍和比较了Glide与Picasso,总体来说二者极为相似,有着近乎相同的API的使用风格。但Glide在缓存策略和加载GIF方面略胜一筹。最后作者也极力推荐了这个库。

而且据说在Google新出的Photos应用中,到处可见Glide的踪迹。看到这里,你是不是已经迫不及待的想试一试这个库呢?就在你下定决心尝试一记的时候,你又听说Yelp app(据说是美国的大众点评)也在使用这个吊炸天的库。你的心中激动万分,发四一定要使用这个库。说干就干,打开Android Studio,在builde.gradle里面添加上

compile ‘com.github.bumptech.glide:glide:3.6.1‘

然后全局搜索图片加载的地方,全部换成了下面的代码:

Glide.with(mContext)
        .load(url)
        .placeholder(R.drawable.loading_spinner)
        .crossFade()
        .into(myImageView);

在经过漫长的编译过程之后,再次打开APP,看到有着渐现效果的图片呈现在你的面前,你不禁叫道:“wocao,真TM帅!为什么我以前没有发现呢?”。

不过在你使用了几天之后你会发现一些问题:

为什么 有的图片第一次加载的时候只显示占位图,第二次才显示正常的图片呢?

为什么 我总会得到类似You cannot start a load for a destroyed activity这样的异常呢?

为什么 我不能给加载的图片setTag()呢?

为什么?为什么?这么NB的库竟然会有这么多的问题。没错,这就是我今天要讲的重点。怎么避免上面的问题发生。

一些解决方案

1.如果你刚好使用了这个圆形Imageview库或者其他的一些自定义的圆形Imageview,而你又刚好设置了占位的话,那么,你就会遇到第一个问题。如何解决呢?

方案一: 不设置占位;
方案二:使用Glide的Transformation API自定义圆形Bitmap的转换。这里是一个已有的例子
方案三:使用下面的代码加载图片:

Glide.with(mContext)
    .load(url)
    .placeholder(R.drawable.loading_spinner)
    .into(new SimpleTarget<Bitmap>(width, height) {
        @Override
        public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
            // setImageBitmap(bitmap) on CircleImageView
        }
    };

2.至于第二个问题,请记住一句话:不要再非主线程里面使用Glide加载图片,如果真的使用了,请把context参数换成getApplicationContext。更多的细节请参考这个issue

3.为什么不能设置Tag,是因为你使用的姿势不对哦。如何为ImageView设置Tag呢?且听我细细道来。

方案一:使用setTag(int,object)方法设置tag,具体用法如下:

Java代码是酱紫的:

Glide.with(context).load(urls.get(i).getUrl()).fitCenter().into(imageViewHolder.image);
        imageViewHolder.image.setTag(R.id.image_tag, i);
        imageViewHolder.image.setOnClickListener(new View.OnClickListener() {
            @Override
                int position = (int) v.getTag(R.id.image_tag);
                Toast.makeText(context, urls.get(position).getWho(), Toast.LENGTH_SHORT).show();
            }
        });

同时在values文件夹下新建ids.xml,添加

<item name="image_tag" type="id"/>

大功告成!

方案二:从Glide的3.6.0之后,新添加了全局设置的方法。具体方法如下:

先实现GlideMoudle接口,全局设置ViewTaget的tagId:

public class MyGlideMoudle implements GlideModule{
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        ViewTarget.setTagId(R.id.glide_tag_id);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {

    }
}

同样,也需要在ids.xml下添加id

<item name="glide_tag_id" type="id"/>

最后在AndroidManifest.xml文件里面添加

<meta-data
    android:name="com.yourpackagename.MyGlideMoudle"
    android:value="GlideModule" />

又可以愉快的玩耍了,嘻嘻`(∩_∩)′。

方案三:写一个继承自ImageViewTaget的类,复写它的get/setRequest方法。

Glide.with(context).load(urls.get(i).getUrl()).fitCenter().into(new ImageViewTarget<GlideDrawable>(imageViewHolder.image) {
            @Override
            protected void setResource(GlideDrawable resource) {
                imageViewHolder.image.setImageDrawable(resource);
            }

            @Override
            public void setRequest(Request request) {
                imageViewHolder.image.setTag(i);
                imageViewHolder.image.setTag(R.id.glide_tag_id,request);
            }

            @Override
            public Request getRequest() {
                return (Request) imageViewHolder.image.getTag(R.id.glide_tag_id);
            }
        });

        imageViewHolder.image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = (int) v.getTag();
                Toast.makeText(context, urls.get(position).getWho(), Toast.LENGTH_SHORT).show();
            }
        });

一些使用技巧

1.Glide.with(context).resumeRequests()和 Glide.with(context).pauseRequests()

当列表在滑动的时候,调用pauseRequests()取消请求,滑动停止时,调用resumeRequests()恢复请求。这样是不是会好些呢?

2.Glide.clear()

当你想清除掉所有的图片加载请求时,这个方法可以帮助到你。

3.ListPreloader

如果你想让列表预加载的话,不妨试一下ListPreloader这个类。

一些基于Glide的优秀库

1.glide-transformations

一个基于Glide的transformation库,拥有裁剪,着色,模糊,滤镜等多种转换效果,赞的不行不行的~~

2.GlidePalette

一个可以在Glide加载时很方便使用Palette的库。

时间: 2024-11-07 05:05:23

Android 平滑图片加载和缓存库 Glide 使用详解的相关文章

【PullToRefresh 系列一】 Android上拉加载下拉刷新控件详解

转载请注明:http://blog.csdn.net/duguang77/article/details/40921601 作者信息: PullToRefresh控件下载地址:https://github.com/chrisbanes/Android-PullToRefresh 作者:https://github.com/chrisbanes 百度网盘下载地址:http://pan.baidu.com/s/1o6umifw (一)导入方法: 1.下载后将extras,library,sample

Android图片加载与缓存开源框架:Android Glide

<Android图片加载与缓存开源框架:Android Glide> Android Glide是一个开源的图片加载和缓存处理的第三方框架.和Android的Picasso库类似,个人感觉比Android Picasso好用.Android Glide使自身内部已经实现了缓存策略,使得开发者摆脱Android图片加载的琐碎事务,专注逻辑业务的代码.Android Glide使用便利,短短几行简单明晰的代码,即可完成大多数图片从网络(或者本地)加载.显示的功能需求. 使用Android Gl

SDWebImage使用,图片加载和缓存

SDWebImage使用,图片加载和缓存 2012-12-14 12:28:12|  分类: iOS|举报|字号 订阅 下载LOFTER我的照片书  | 清除缓存: [[SDImageCache sharedImageCache] clearDisk]; [[SDImageCache sharedImageCache] clearMemory]; 来自:http://blog.csdn.net/sqc3375177/article/details/7714573 SDWebImage托管在git

SDWebImage 图片加载和缓存

SDWebImage托管在github上.https://github.com/rs/SDWebImage 这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL下载次数控制和优化等特征.使用示范的代码: UITableView使用UIImageView+WebCache类(基本应用,UIImageView的一个category) 前提#import导入UIImageView+WebCache.h文件,然后在tableview的cellFor

android webView 图片加载不出来 后台报错Uncaught TypeError: Cannot call method &#39;getElementsByTagName&#39; of null

在之前,webView加载图片完全没有问题.直到前端H5开发换新的加载图片的方式,导致图片忽然加载不出来了. 从后台日志看到了webview 打印了报错信息 Cannot call method 'getElementsByTagName' of null 我怀疑是不是由于此处报错终止了图片加载的进程. 分析此处错误出现的原因: 由于调用的H5界面的js其中的写法不规范,webView在加载的时候,调用的doom模型为空,导致了其图片没有加载出来 解决办法: 在客户端webView.getSet

iOS开发——加载、滑动翻阅大量图片解决方案详解

加载.滑动翻阅大量图片解决方案详解 今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清大图全屏浏览界面的这短暂的1秒内(和后续的几秒),都发生了什么. 常规思路流程 点击任意小图后, 1.首先制作scrollview框架:大小2个scrollview,小的用于手势缩放单一图片,大的横向依次加载全部照片 2.制作好scrollview框架后,加载照片 3.一切准备就绪跳转页面呈现给用户选择的大

Android批量图片加载经典系列——采用二级缓存、异步加载网络图片

一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络.内存缓存(一级)本质上是Map集合以key-value对的方式存储图片的url和Bitmap信息,由于内存缓存会造成堆内存泄露, 管理相对复杂一些,可采用第三方组件,对于有经验的可自己编写组件,而文件缓存比较简单通常自己封装一下即可.下面就通过案例看如何实现网络图片加载的优化. 二.案例介绍 案例新

Android批量图片加载经典系列——afinal框架实现图片的异步缓存加载

一.问题描述 在之前的系列文章中,我们使用了Volley和Xutil框架实现图片的缓存加载(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html#pltpjz),接下来我们再介绍一下afinal 框架的使用. Afinal 是一个android的http框架.sqlite orm 和 ioc 框架.使其更加简单易用,Afinal的宗旨是简洁,快速.约定配置的方式之后,尽量一行代码完成所有事情,代码入侵性小,在三者中比较推荐.在这里我们主要使用

Android批量图片加载经典系列——使用xutil框架缓存、异步加载网络图片

一.问题描述 为提高图片加载的效率,需要对图片的采用缓存和异步加载策略,编码相对比较复杂,实际上有一些优秀的框架提供了解决方案,比如近期在git上比较活跃的xutil框架 Xutil框架提供了四大模块: 1.  DbUtil模块:采用ORM机制简化Sqlite操作,一行代码就可执行增删改查.支持事务.支持延迟策略 2.  ViewUtils模块:可以说是Android的IOC框架,可以注解方式对ui.资源.事件进行绑定 3.  HttpUtils模块:支持同步.异步请求.支持大文件上传 4.