首页 > 其他分享 >Glide多种组合使用方式记录--没有全部亲测,大家可以根据实际需要选用

Glide多种组合使用方式记录--没有全部亲测,大家可以根据实际需要选用

时间:2023-09-19 13:34:20浏览次数:50  
标签:load Glide get -- submit context new 亲测


官方使用建议:

// For a simple view:
@Override 
public void onCreate(Bundle savedInstanceState) {
  ...
  ImageView imageView = (ImageView) findViewById(R.id.my_image_view);

  Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
}

// For a simple image list:
@Override 
public View getView(int position, View recycled, ViewGroup container) {
  final ImageView myImageView;
  if (recycled == null) {
    myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);
  } else {
    myImageView = (ImageView) recycled;
  }

  String url = myUrls.get(position);

  Glide
    .with(myFragment)
    .load(url)
    .centerCrop()
    .placeholder(R.drawable.loading_spinner)
    .into(myImageView);
  return myImageView;
}

官方指导RecyclerView使用时加载图片

有时在使用 RecyclerView时,View 可能被重用且保持了前一个位置的尺寸,但在当前位置会发生改变。为了处理这种场景,你可以创建一个新的 ViewTarget 并为 waitForLayout() 方法传入 true:

@Override
public void onBindViewHolder(VH holder, int position) {
  Glide.with(fragment)
    .load(urls.get(position))
    .into(new DrawableImageViewTarget(holder.imageView, /*waitForLayout=*/ true));

优化性能指导

清理

当你完成了对资源(Bitmap,Drawable 等)的使用时,及时清理(clear)你创建的这些 Target 是一个好的实践。即使你认为你的请求已经完成了,也应该使用 clear() 以使 Glide 可以重用被这次加载使用的任何资源 (特别是 Bitmap )。未调用 clear() 会浪费 CPU内存阻塞更重要的加载,甚至如果你在同一个 surface (View, Notification, RPC 等) 上有两个 Target,可能会引发图片显示错误。对于像 SimpleTarget这种无法从一个新实例里跟踪前一个请求的 Target 来说,及时清理尤为重要。

Glide.with(fragment)
  .load(url)
  .into(imageView);

// Some time in the future:
Glide.with(fragment).clear(imageView);

动画资源和定制目标

Glide.with(fragment)
  .asGif()
  .load(url)
  .into(new SimpleTarget<>() {
    @Override
    public void onResourceReady(GifDrawable resource, Transition<GifDrawable> transition) {
      resource.start();
      // Set the resource wherever you need to use it.
    }
  });

如果你加载的是 Bitmap 或 GifDrawable,你可以判断这个可绘制对象是否实现了 Animatable:

Glide.with(fragment)
  .load(url)
  .into(new SimpleTarget<>() {
    @Override
    public void onResourceReady(Drawable resource, Transition<GifDrawable> transition) {
      if (resource instanceof Animatable) {
        resource.start();
      }
      // Set the resource wherever you need to use it.
    }
  });

注意

Android中的动画代价是比较大的,尤其是同时开始大量动画的时候。 交叉淡入和其他涉及 alpha 变化的动画显得尤其昂贵。 此外,动画通常比图片解码本身还要耗时。在列表和网格中滥用动画可能会让图像的加载显得缓慢而卡顿。为了提升性能,请在使用 Glide 向 ListView , GridView, 或 RecyclerView 加载图片时考虑避免使用动画,尤其是大多数情况下,你希望图片被尽快缓存和加载的时候。作为替代方案,请考虑预加载,这样当用户滑动到具体的 item 的时候,图片已经在内存中了。

对占位符和透明图片交叉淡入【官方提醒】

虽然禁用交叉淡入通常是一个比较好的默认行为,当待加载的图片包含透明像素时仍然可能造成问题。当占位符比实际加载的图片要大,或者图片部分为透明时,禁用交叉淡入会导致动画完成后占位符在图片后面仍然可见。如果你在加载透明图片时使用了占位符,你可以启用交叉淡入,具体办法是调整 DrawableCrossFadeFactory 里的参数并将结果传到 transition() 中:

DrawableCrossFadeFactory factory =
        new DrawableCrossFadeFactory.Builder().setCrossFadeEnabled(true).build();

GlideApp.with(context)
        .load(url)
        .transition(withCrossFade(factory))
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .placeholder(R.color.placeholder)
        .into(imageView);

以前屏幕比较小,列表图片和一些图片加载展现的尺寸不大,所以就算有图片叠加问题不留意也看不出来。
但是最近的网络电视流行。图片加载尺寸越来越大这个问题就有可能比较严重了。尤其进行TV开发者留意

应用程序(Applications)和程序库 (Libraries)使用建议

应用程序(Applications)如果希望使用集成库和/或 Glide 的 API 扩展,则需要:

恰当地添加一个 AppGlideModule 实现。
(可选)添加一个或多个 LibraryGlideModule 实现。
给上述两种实现添加 @GlideModule 注解。
添加对 Glide 的注解解析器的依赖。
在 proguard 中,添加对 AppGlideModules 的 keep 。

@GlideModule
public class FlickrGlideModule extends AppGlideModule {
  @Override
  public void registerComponents(Context context, Registry registry) {
    registry.append(Photo.class, InputStream.class, new FlickrModelLoader.Factory());
  }
}

程序库如果需要注册定制组件,例如 ModelLoader,可按以下步骤执行:

添加一个或多个 LibraryGlideModule 实现,以注册新的组件。
为每个 LibraryGlideModule 实现,添加 @GlideModule 注解。
添加 Glide 的注解处理器的依赖。
一个 [LibraryGlideModule] 的例子,在 Glide 的OkHttp 集成库 中:

@GlideModule
public final class OkHttpLibraryGlideModule extends LibraryGlideModule {
  @Override
  public void registerComponents(Context context, Glide glide, Registry registry) {
    registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
  }
}

避免在程序库中使用 AppGlideModule

程序库一定 不要 包含 AppGlideModule 实现。这么做将会阻止依赖该库的任何应用程序管理它们的依赖,或配置诸如 Glide 缓存大小和位置之类的选项。

此外,如果两个程序库都包含 AppGlideModule,应用程序将无法在同时依赖两个库的情况下通过编译,而不得不在二者之中做出取舍。

这确实意味着程序库将无法使用 Glide 的 generated API,但是使标准的 RequestBuilder 和 RequestOptions 加载仍然有效(可以在 选项 页找到例子)

冲突

应用程序可能依赖多个程序库,而它们每一个都可能包含一个或更多的 LibraryGlideModules 。在极端情况下,这些 LibraryGlideModules 可能定义了相互冲突的选项,或者包含了应用程序希望避免的行为。应用程序可以通过给他们的 AppGlideModule 添加一个 @Excludes 注解来解决这种冲突,或避免不需要的依赖。

例如,如果你依赖了一个库,它有一个 LibraryGlideModule 叫做com.example.unwanted.GlideModule,而你不想要它:

@Excludes(com.example.unwanted.GlideModule)
@GlideModule
public final class MyAppGlideModule extends AppGlideModule { }

你也可以排除多个模块:

@Excludes({com.example.unwanted.GlideModule, com.example.conflicing.GlideModule})
@GlideModule
public final class MyAppGlideModule extends AppGlideModule { }

@Excludes 注解不仅可用于排除 LibraryGlideModules 。如果你还在从 Glide v3
到新版本的迁移过程中,你还可以用它来排除旧的,废弃的 GlideModule 实现

【省流量模式】仅从缓存加载图片

某些情形下,你可能希望只要图片不在缓存中则加载直接失败(比如省流量模式)。如果要完成这个目标,你可以在单个请求的基础上使用 onlyRetrieveFromCache 方法:

Glide.with(fragment)
  .load(url)
  .onlyRetrieveFromCache(true)
  .into(imageView);

如果图片在内存缓存或在磁盘缓存中,它会被展示出来。否则只要这个选项被设置为 true ,这次加载会视同失败。

【图片验证码】跳过缓存

如果你想确保一个特定的请求跳过磁盘和/或内存缓存(比如,图片验证码 ),Glide 也提供了一些替代方案。

仅跳过内存缓存,请使用 skipMemoryCache() :

Glide.with(fragment)
  .load(url)
  .skipMemoryCache(true)
  .into(view);

仅跳过磁盘缓存,请使用 DiskCacheStrategy.NONE :

Glide.with(fragment)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.NONE)
  .into(view);

这两个选项可以同时使用:

Glide.with(fragment)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.NONE)
  .skipMemoryCache(true)
  .into(view);

从源码解析的时候发现的使用方式粗略有25种组合

* @see Glide#with(android.app.Activity)
 * @see Glide#with(androidx.fragment.app.FragmentActivity)
 * @see Glide#with(android.app.Fragment)
 * @see Glide#with(androidx.fragment.app.Fragment)
 * @see Glide#with(Context)
 *

//源码使用方式一

FutureTarget<Bitmap> target =
        Glide.with(app)
            .asBitmap()
            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
            .skipMemoryCache(true)
            .override(targetSize)
            .load(resourceId)
            .listener(
                new RequestListener<Bitmap>() {
                  @Override
                  public boolean onl oadFailed(
                      @Nullable GlideException e,
                      Object model,
                      Target<Bitmap> target,
                      boolean isFirstResource) {
                    return false;
                  }

                  

@Override
                  public boolean onResourceReady(
                      Bitmap resource,
                      Object model,
                      Target<Bitmap> target,
                      DataSource dataSource,
                      boolean isFirstResource) {
                    dataSourceRef.set(dataSource);
                    return false;
                  }
                })
            .submit();
            ....
    Glide.with(app).clear(target);

//用法二

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), ResourceIds.raw.canonical);
    byte[] data = concurrency.get(Glide.with(context).as(byte[].class).load(bitmap).submit());

//三

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), ResourceIds.raw.canonical);
    byte[] data =
        concurrency.get(
            Glide.with(context)
                .as(byte[].class)
                .load(new BitmapDrawable(context.getResources(), bitmap))
                .submit());

//4

byte[] data =concurrency.get(Glide.with(context).as(byte[].class).load(ResourceIds.raw.video).submit());

//5

Glide.with(context).as(byte[].class).load(writeVideoToFile()).submit()

//6

byte[] data =
        concurrency.get(
            Glide.with(context)
                .as(byte[].class)
                .load(writeVideoToFile().getAbsolutePath())
                .submit());

//7

byte[] data =
        concurrency.get(
Glide.with(context).as(byte[].class).load(Uri.fromFile(writeVideoToFile())).submit());

//8

Glide.with((Context) ApplicationProvider.getApplicationContext()).clear(imageView);

//9

Bitmap bitmap =
        concurrency.get(
Glide.with(context).asBitmap().load(getDataUriString(CompressFormat.JPEG)).submit());
 Bitmap bitmap =
        concurrency.get(
            Glide.with(context).asBitmap().load(getDataUriString(CompressFormat.PNG)).submit());
Bitmap bitmap =
        concurrency.get(
            Glide.with(context).asBitmap().load(getDataUri(CompressFormat.JPEG)).submit());
            ...
            private Uri getDataUri(CompressFormat format) {
    return Uri.parse(getDataUriString(format));
  }
            private String getDataUriString(CompressFormat format) {
    String bytes = getBase64BitmapBytes(format);
    String imageType;
    switch (format) {
      case PNG:
        imageType = "png";
        break;
      case JPEG:
        imageType = "jpeg";
        break;
      case WEBP:
        imageType = "webp";
        break;
      default:
        throw new IllegalArgumentException("Unrecognized format: " + format);
    }

    String mimeType = "image/" + imageType;
    return "data:" + mimeType + ";base64," + bytes;
  }
  ...
  private String getBase64BitmapBytes(CompressFormat format) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Drawable drawable =
        Preconditions.checkNotNull(ContextCompat.getDrawable(context, ResourceIds.raw.canonical));
    Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
    bitmap.compress(format, 100, bos);
    byte[] data = bos.toByteArray();
    return Base64.encodeToString(data, /*flags=*/ 0);
  }

//10

Drawable colorDrawable = new ColorDrawable(Color.RED);
    Drawable result =
        Glide.with(context)
            .load(colorDrawable)
            .apply(new RequestOptions().optionalCenterCrop())
            .submit()
            .get();
 =====================
Drawable result =
        Glide.with(context)
            .load(colorDrawable)
            .apply(new RequestOptions().centerCrop())
            .submit(100, 100)
            .get();

//11

Glide.with(context).load(ResourceIds.raw.canonical).listener(requestListener).submit()

//12

Drawable drawable = concurrency.get(Glide.with(context).load(raw.canonical).submit());

//13

Glide.with(app)
          .load(loadStep.getModel(beforeData))
          .diskCacheStrategy(DiskCacheStrategy.NONE)
          .override(Target.SIZE_ORIGINAL)
          .submit()
          .get(15, TimeUnit.SECONDS);

//14

Glide.with(app)
                .as(Baz.class)
                .load(model)
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE));

//15

Glide.with(getContext()).asDrawable().load(android.R.drawable.ic_menu_rotate).into(this);

//16

byte[] data = getLargeImageBytes();
    Bitmap bitmap = concurrency.get(Glide.with(context).asBitmap().load(data).submit());

//17

ByteBuffer buffer = ByteBuffer.wrap(getLargeImageBytes());
    Bitmap bitmap = concurrency.get(Glide.with(context).asBitmap().load(buffer).submit());

//18

Glide.with(context).load(canonicalBytes).apply(skipMemoryCacheOf(false))

//19

Glide.with(context).asDrawable().load(canonicalBytes).apply(skipMemoryCacheOf(false)

//20

Drawable frame = concurrency.get(Glide.with(context).load(ResourceIds.raw.video).submit());

//21

Drawable frame =
        concurrency.get(Glide.with(context).load(new Integer(ResourceIds.raw.video)).submit());

//22

Bitmap frame =
        concurrency.get(Glide.with(context).asBitmap().load(ResourceIds.raw.video).submit());

//23

Drawable drawable =
        Glide.with(context)
            .load(android.R.drawable.star_big_off)
            .apply(centerCropTransform())
            .submit()
            .get();

//24

Drawable drawable =
        Glide.with(context)
            .load(ResourceIds.drawable.shape_drawable)
            .apply(bitmapTransform(new RoundedCorners(10)))
            .submit(100, 200)
            .get();
Bitmap bitmap =
        Glide.with(context)
            .asBitmap()
            .load(ResourceIds.drawable.shape_drawable)
            .submit(100, 200)
            .get();
Bitmap bitmap =
        Glide.with(context)
            .asBitmap()
            .load(ResourceIds.drawable.shape_drawable)
            .apply(centerCropTransform())
            .submit(100, 200)
            .get();

//25

Bitmap bitmap = Glide.with(context).asBitmap().load(uri).submit().get();
Bitmap bitmap =        Glide.with(context).asBitmap().apply(centerCropTransform()).load(uri).submit().get();
Drawable drawable = Glide.with(context).load(uri).submit().get();

丰富的gilde使用方式,总有一款适合你

总结

  • 使用上非常简洁 glide陪伴着android系统一起成长。
  • 其中的设计理念和设计实践都很值得App开发者学习和借鉴
  • 后期将从设计模式、算法、测试的几个角度深度解析Glide源码工程。
  • 如果发现很好的实践将会单独摘出来说明使用环境和条件

自研产品推荐

历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:

  • api参数填写
  • api请求响应数据展示
  • PDF形式的分享文档
  • Mock本地化解决方案
  • api列表数据本地化处理
  • 再加上UI方面的打磨

为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。

嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!

下面是一段smartApi使用介绍:

Glide多种组合使用方式记录--没有全部亲测,大家可以根据实际需要选用_面向对象编程

下载地址:

https://pan.baidu.com/s/1kFAGbsFIk3dDR64NwM5y2A?pwd=csdn


标签:load,Glide,get,--,submit,context,new,亲测
From: https://blog.51cto.com/u_16264967/7524373

相关文章

  • CSRF-介绍
    CSRF:跨站请求伪造(Cross-siterequestforgery)CSRF是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。当用户访问含有恶意代码的网页时,会向指定正常网站发送非本人意愿的数据请求包(如转账给hack,向hack发送API等)如果此时用户恰好登录了该正常网站(也就是身份......
  • 关联式数据结构_红黑树剖析 #C++
    红黑树的性质和定义红黑树的性质红黑树是一种平衡搜索二叉树。红黑树的每个节点存储了一个标记颜色的变量(红色或黑色),通过对任意一条从根到叶子结点的路径中节点着色方式的限制,使树的最长路径不超过最短路径的两倍,因而红黑树处于一种近似平衡的状态。与AVL树相比,红黑的平衡条件更......
  • Cert-Manager 实现基于阿里云的自动证书签发
    简介Cert-Manager[1]是一款用于Kubernetes集群中自动化管理TLS证书的开源工具,它使用了Kubernetes的自定义资源定义(CRD)机制,让证书的创建、更新和删除变得非常容易。设计理念Cert-Manager是将TLS证书视为一种资源,就像Pod、Service和Deployment一样,可以使用Kuberne......
  • Docker 日志缓存过大清理方案(亲测)
    Docker日志缓存过大清理方案(亲测)docker磁盘不足异常现象记录排查并定位问题解决方案参考地址自研产品推荐下载地址:docker磁盘不足异常现象记录docker-composeINTERNALERROR:cannotcreatetemporarydirectory!排查并定位问题1#查看磁盘占用情况[root@iZ25bmxsqmeZ~]#df......
  • 文心一言 VS 讯飞星火 VS chatgpt (96)-- 算法导论9.3 1题
    一、用go语言,在算法SELECT中,输人元素被分为每组5个元素。如果它们被分为每组7个元素,该算法仍然会是线性时间吗?证明:如果分成每组3个元素,SELECT的运行时间不是线性的。文心一言:在算法分析中,一个算法的运行时间是否线性依赖于其输入数据的大小。线性时间意味着算法的运行......
  • Glide源码阅读之适配器模式【ArrayAdapterInterface<T>】
    定义菜鸟教程介绍意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。何时使用:1、系统需要使......
  • 最小二乘法求解线性回归模型
    ✅作者简介:热爱科研的算法开发者,Python、Matlab项目可交流、沟通、学习。......
  • 容器技术:容器运行时
    什么是运行时(runtime)?runtime指的是程序执行时所需要的环境,以确保程序能够在特定的环境中正确运行;runtime为程序提供运行所需要的各种功能和支持,包括但不限于操作系统、编程语言的运行时库、虚拟机或解释器;Java程序文件就好比是容器镜像文件,JVM则好比是runtime,运行起来的Java程序......
  • RK3568开发笔记(十):开发板buildroot固件移植开发的应用Demo,启动全屏显示
    前言  上一篇,移植应用前的通讯接口工作和全屏工作都已经完成了。本篇移植开发的商业应用。<br>交叉编译好应用  (略),参照《RK3568开发笔记(八):开发板烧写buildroot固件(支持hdmi屏),搭建Qt交叉编译开发环境,编译一个Demo,目标板运行Demo测试》<br>解决全屏标题栏占用问题  交叉......
  • 自动检测MultiIndex的维数并全部转化为整数
    将pd.MultiIndex.from_tuples(  [(int(a),int(b))fora,binmy_df.index],  names=my_df.index.names)改写为自动检测MultiIndex的维数并全部转化为整数的函数importpandasaspdimportnumpyasnp#YouroriginalDataFramemy_df=pd.DataFrame(np.add......