Glide 是谷歌推荐的Android 图片加载框架,他的优点不用多说。随着云服务的兴起,七牛的图片存储也逐渐被大众所接受,然而,部分图片为了存储的安全性,七牛采用了动态 token 生成 图片url 的做法,通常情况下,图片加载框架是以图片的URL 为缓存的唯一标识的,Glide 也不例外。
七牛的动态URL使得同一张图片每次加载时的地址都不相同,我们也知道,通常情况下,像 picasso Android-Universal-Image-Loader 等图片的缓存都是基于URL全路径做为缓存的标识与依据的, Glide 也不例外,那么问题就产生了,如何缓存动态的url 图呢? 我们总不能每次都从服务器加载同一张图片吧,即使那个图片很小,也最好不要每次都浪费这必要的流量。
问题的根本是缓存时的唯一标识符不能变。根据这一要求,我样可以有两种选择:一 修改Glide 框架源码,让其自动识别七牛 图片地址并做特殊处理。二 采用偷梁换柱的方法,让Glide 每次应对同一张图片的不同地址时都加载最早一次的缓存, 如果在本地磁盘找到缓存根本就不需再访问网络。
为了一个七牛显然不值得去修改 Glide 源码。为此,我们主要是介绍第二种方法。在缓存地址上下文章。
http://xiangbalao.org/FlopaR58EF90fqHBzPAWeroBTnwK?imageView2/2/w/200/h/2002/w/200/h/200&e=1469352718&token=wQknukoe-lwcjLKEnsBzBrL61M1BEMP0Gq_M2qP:uyLFpK8vQXeM9qegAeT1P2OzSls=
这是一个典型的 七牛动态 URL ,通过我们分析,我们发现,这个 url 其实是分为三部分的 :1 不动的基地址,2用来来示参数的问号, 3 动态的 token 等参数
http://xiangbalao.org/FlopaR58EF90fqHBzPAWeroBTnwK
?
imageView2/2/w/200/h/2002/w/200/h/200&e=1469352718&token=wQknukoe-lwcjLKEnsBz-
BrL61M1BEMP0Gq_M2qP:uyLFpK8vQXeM9qegAeT1P2OzSls=
听起来似乎很绕,直接上代码
package org.xiangbalao.glide; import android.content.Context; import android.widget.ImageView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.drawable.GlideDrawable; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.target.Target; import com.orhanobut.hawk.Hawk; /** * Created by longtaoge on 2016/7/25. */ public class GlideUtils { // public static String slipTag = "\\?"; //加载七牛时用本分隔符 public static String slipTag = "it"; public static void loadImage(final Context context, final String url, final ImageView imageView) { if (url != null) { String[] urls = url.split(slipTag); if (urls.length > 1) { if (Hawk.get(getCacheUrl(url)) == null) {//用图片URL固定的部分获取第一次缓存图片时的全URL Hawk.put(getCacheUrl(url), url); //如果没有缓存过,将第图片第一次加载时的URL缓存起来 //第一次加载用全路径从网络上加载 Glide.with(context) .load(url) .into(imageView); } else { //第二次以后能过 url 加载本地缓存图片 Glide.with(context) .load(String.valueOf(Hawk.get(getCacheUrl(url)))) // 设置加载失败监听,假如由于缓存过期或 // 者被清等客观原因导致加载失败,从最新的url 加载,并更新本地缓存 .listener(new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) { Glide.with(context) .load(url) .into(imageView); return false; } @Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { Hawk.put(getCacheUrl(url), url); //更新缓存 return false; } }) .into(imageView); } } else { //如果非动态URL 则直接加载即可 Glide.with(context) .load(url) .into(imageView); } } } public static String getCacheUrl(String url) { if (url != null) { String[] urls = url.split(slipTag); if (urls.length > 0) { return urls[0]; } else { return ""; } } else { return ""; } } }