在图片加载库烂大街的今天,选择一个适合自己使用的图片加载库已经成为了每一个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的库。

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

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

    <Android图片加载与缓存开源框架:Android Glide> Android Glide是一个开源的图片加载和缓存处理的第三方框架.和Android的Picasso库类似,个人感觉 ...

  2. AntiModerate – 渐进式图片加载的 JavaScript 库

    AntiModerate 是一个渐进式图片加载的 JavaScript 库.我们多数看到的图片显示模式,都是从上到下逐渐显示的,这是“标准式”图像:而有的图片是先出现一个很低分辨率的图像轮廓,类似加了 ...

  3. 主流图片加载框架 ImageLoader、Glide、Picasso、Fresco 对比

    图片缓存库主页: Glidehttps://github.com/bumptech/glide fresco - An Android library for managing images and ...

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

    加载.滑动翻阅大量图片解决方案详解     今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...

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

    一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络. ...

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

    一.问题描述 为提高图片加载的效率,需要对图片的采用缓存和异步加载策略,编码相对比较复杂,实际上有一些优秀的框架提供了解决方案,比如近期在git上比较活跃的xutil框架 Xutil框架提供了四大模块 ...

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

    一.问题描述 在之前的系列文章中,我们使用了Volley和Xutil框架实现图片的缓存加载(查看系列文章:http://www.cnblogs.com/jerehedu/p/4607599.html# ...

  8. Android 三大图片加载框架的对比——ImageLoader,Picasso,Glide

    一.ImageLaoder介绍 << Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹ass ...

  9. Android之图片加载框架Fresco基本使用(二)

    PS:最近看到很多人都开始写年终总结了,时间过得飞快,又到年底了,又老了一岁. 学习内容: 1.进度条 2.缩放 3.ControllerBuilder,ControllerListener,Post ...

随机推荐

  1. oracle中简单查询语句的格式及执行顺序分析

    一条简单的查询sql格式如下: SELECT ... FROM .... [WHERE ...] --过滤单行 [GROUP BY ...   [HAVING ...]]--GROUP BY对前面wh ...

  2. mysqlbinlog恢复数据

    操作命令: 复制代码代码如下: show binlog events in 'mysql-bin.000016' limit 10; reset master 删除所有的二进制日志flush logs ...

  3. IOS网络开发实战(一)

      1 局域网群聊软件 1.1 问题 UDP协议将独立的数据包从一台计算机传输到另外一台计算机,但是并不保证接受方能够接收到该数据包,也不保证接收方所接收到的数据和发送方所发送的数据在内容和顺序上是完 ...

  4. OpenGL ES 2.0 摄像机与投影

    1.摄像机的设置 摄像机的位置坐标 摄像机的位置 摄像机up方向 Matrix.setLookAtM( mVMatrix, //存储生成矩阵元素的float[]类型数组 0, //填充起始偏移量 cx ...

  5. BZOJ 1003 物流运输 (动态规划 SPFA 最短路)

    1003: [ZJOI2006]物流运输 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5590 Solved: 2293 [Submit][Stat ...

  6. C#通过生成ini文件,记住用户关闭程序之前的选择+忽略跨线程检查

    1.在类的里面添加 //写配置文件 [DllImport("kernel32")] private static extern long WritePrivateProfileSt ...

  7. 数值运算内建函数(core python programming 2nd edition 5.6.2)

    数值运算内建函数 函数  功能 abs(num) 返回 num 的绝对值 coerce(num1, num2) 将num1和num2转换为同一类型,然后以一个元组的形式返回. divmod(num1, ...

  8. memcached的安装

    最近在研究怎么让Discuz!去应用Memcache去做一些事情,记录下Memcache安装的过程. Linux下Memcache服务器端的安装 服务器端主要是安装memcache服务器端,目前的最新 ...

  9. CSU 1335 高桥和低桥

    开始队友说是线段树,看了看貌似也是,上手敲了个嵌套的线段树,O(nlognlogn)的复杂度果断tle了 TAT 思路:对h[i]排序,对每次涨水退水,先用二分查找,再用一个数组保存当前点之后所有点被 ...

  10. 百度地图api实例

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm11.aspx ...