Glide 加载 七牛 动态url 图片并缓存

                 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=

 

  只要能找到唯一标识符就好办了,这样我样可以写一个工具类,做一个url缓存,当发现我们第一次加载本图时,从服务器直接加载,这时,Glide 已经将图缓存在了本地。我们用 通过?号前面的地址将这个图片的缓存url存起来,当下次加载本图时,如果发现有本url 的缓存,直接取出来,Glide就可以从本地加载本图了。

    听起来似乎很绕,直接上代码

 
 

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 "";
        }

    }


}

本例地址 GlideDemoActivity.java 







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 怎么办? 这个问题可以通过使用异常处理来解决。你可以在Glide的请求中捕获异常,并在异常发生时使用默认图像。例如: ``` try { Glide.with(context) .load(url) .into(imageView); } catch (Exception e) { Glide.with(context) .load(R.drawable.default_image) .into(imageView); } ``` 这样,如果图像加载失败,Glide就会使用默认图像代替。 ### 回答2: Android Glide是一个流行的图片加载库,它可以方便地加载网络上的图片并进行缓存。当遇到加载失败的URL时,我们可以通过一些额外的步骤来缓存一个默认的Bitmap图片。下面是一个可能的实现方式: 首先,我们需要为Glide配置一个失败时的回调,即使用`error()`方法指定一个加载失败时显示的图片资源。 ```java Glide.with(context) .load(url) .error(R.drawable.default_image) // 设置加载失败时显示的图片 .into(imageView); ``` 然后,我们可以使用Glide的生命周期方法来监听图片加载的结果,其中的`onLoadFailed()`方法会在加载失败时被调用。我们可以在该方法中获取失败的URL,然后使用`Signature.obtain()`来创建一个唯一标识符,并将其存储到Glide缓存中。 ```java Glide.with(context) .load(url) .error(R.drawable.default_image) .signature(new StringSignature(url)) // 使用URL作为唯一标识符 .listener(new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { // 从失败的URL中创建唯一标识符 Signature signature = new StringSignature(url); // 获取Glide缓存 DiskCache cache = Glide.get(context).getDiskCache(); try { // 检查缓存中是否已存在该图片 if (!cache.contains(signature)) { // 如果没有,则加载默认图片,并存储到缓存中 Bitmap defaultBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_image); cache.put(signature, new BitmapDrawable(context.getResources(), defaultBitmap).getBitmap()); } } catch (IOException ex) { ex.printStackTrace(); } return false; } // ... 其他回调方法 }) .into(imageView); ``` 这样,当Glide加载URL图片失败时,会将默认图片存储到缓存中,并在下一次加载同一个URL时使用缓存图片。 需要注意的是,这只是一种实现方式,具体的实现方式可以根据项目的需求进行调整和优化。 ### 回答3: Android Glide 是一个强大的图片加载库,它可以帮助我们更高效地加载和显示图片。对于失败的 URLGlide 也提供了一种方法来缓存图片。 首先,当使用 Glide 加载图片时,可以通过 `.error()` 方法设置一个替代图片,用于在加载失败时显示。这个替代图片可以是一个本地的资源文件,或者是一个已经缓存过的 Bitmap 对象。 接下来,我们可以利用 Glide缓存机制来将成功加载过的图片缓存到本地。Glide 默认会将图片缓存在设备的磁盘上,我们可以通过 `.diskCacheStrategy()` 方法来设置缓存策略。常用的策略包括: 1. `DiskCacheStrategy.ALL`:缓存所有版本的图片,默认策略。 2. `DiskCacheStrategy.NONE`:不缓存任何图片。 3. `DiskCacheStrategy.DATA`:只缓存原始分辨率的图片。 4. `DiskCacheStrategy.RESOURCE`:只缓存资源分辨率的图片。 5. `DiskCacheStrategy.AUTOMATIC`:根据原始图片和 ImageView 的大小来自动判断是否缓存。 如果我们想要将失败的 URL 缓存为 Bitmap 图片,可以先将图片通过其他方式或者其他库下载到本地,并将其转换为 Glide 可以识别的 Bitmap 对象。然后,使用 Glide 的 `.load()` 方法加载这个 Bitmap 对象即可。 需要注意的是,缓存图片可能会占用较多磁盘空间,如果需要在缓存达到一定大小时进行清理,可以使用 `.setMemoryCacheSize()` 方法设置内存缓存的大小,并使用 `.setDiskCacheSize()` 方法设置磁盘缓存的大小。 总之,Android Glide 提供了多种方式来处理失败的 URL缓存图片,我们可以根据具体的需求选择合适的方法进行处理。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值