glide性能优化实战

海哥  金牌会员 | 2024-11-13 00:36:22 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 826|帖子 826|积分 2478

glide性能优化实战

前言

项目利用glide加载图片之前也只是会基本api,这次项目有非常多的图片需要展示,而且设备是一个android12的版本,但是性能不太理想,分给APP的资源不太多,以是需要优化现有图片加载逻辑,读者可以根据自己的项目自行选择优化项。
关于Glide的简单先容

Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及主动的资源池技术。
Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是云云的机动,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide利用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。
虽然Glide 的主要目的是让任何情势的图片列表的滚动尽可能地变得更快、更平滑,但实际上,Glide险些能满意你对远程图片的拉取/缩放/体现的一切需求。
API

Glide 利用简明的流式语法API,这是一个非常棒的计划,因为它允许你在大部门情况下一行代码搞定需求:
  1. Glide.with(context)
  2.     .load(url)
  3.     .into(imageView);
复制代码
性能

Glide 充分考虑了Android图片加载性能的两个关键方面:


  • 图片解码速度
  • 解码图片带来的资源压力
    为了让用户拥有良好的App利用体验,图片不仅要快速加载,而且还不能因为过多的主线程I/O或频繁的垃圾回收导致页面的闪耀和抖动征象。
Glide利用了多个步调来确保在Android上加载图片尽可能的快速宁静滑:


  • 主动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
  • 积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
  • 深度的生命周期集成,以确保仅优先处理活泼的Fragment和Activity的请求,并有利于应用在须要时开释资源以避免在后台时被杀掉。
关于Glide的初步优化

上面都是官网的先容,下面我们进行初步的一个优化。
缓存计谋

起首是图片的缓存计谋。几个可配置的缓存计谋属性在DiskCacheStrategy类中都有先容


  • NONE 不利用缓存,每次都重新加载
  • DATA 在解码之前,将检索到的数据直接写入磁盘缓存。
  • RESOURCE 在解码后,再将检索到的数据写入磁盘缓存。
  • AUTOMATIC 实验根据DataFetcher和EncodeStrategy中的ResourceEncoder(假如ResourceEncoder可用的话)的数据源智能地选择计谋。
  • ALL 假如是远程数据利用DATA和RESOURCE缓存,假如是当地数据利用RESOURCE缓冲。
项目加载的都是当地图片,以是在加载速度和缓存巨细的权衡下,利用了RESOURCE
  1. ...
  2. .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
  3. ...
复制代码
图片裁剪

因为缓存巨细跟图片巨细是有直接关系的,以是加载前最好将其裁剪为和控件巨细一致,避免过大的图片造成ANR和Out Of Memory
  1. ...
  2. .override(your size)
  3. ...
复制代码
移除加载动画

Glide为了保证图片加载的过分流通性,不显得突兀,是有默认的动画和变换的,但这也会斲丧一定的性能,以是我们将它关闭
  1. ...
  2. .dontAnimate()
  3. .dontTransform()
  4. ...
复制代码
其他

(可选)假如需要在加载过程中对图片进行处理,可以利用RequestListener
初步效果

都加上过后大概是这个样子
  1. Glide.with(context)
  2.     .load(url)
  3.         .override(your size)
  4.         .dontAnimate()
  5.     .dontTransform()
  6.         .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
  7.     .into(imageView);
复制代码
可以从Profiler中看到加载一个list的图片时,内存和CPU都有降落。
关于Glide的AppGlideModule定制

在新版Glide中,可以通过自界说AppGlideModule来全局界说glide的设置
  1. import android.content.Context
  2. import com.bumptech.glide.Glide
  3. import com.bumptech.glide.GlideBuilder
  4. import com.bumptech.glide.Registry
  5. import com.bumptech.glide.annotation.GlideModule
  6. import com.bumptech.glide.load.DecodeFormat
  7. import com.bumptech.glide.load.engine.bitmap_recycle.LruArrayPool
  8. import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool
  9. import com.bumptech.glide.load.engine.cache.DiskLruCacheWrapper
  10. import com.bumptech.glide.load.engine.cache.LruResourceCache
  11. import com.bumptech.glide.load.engine.cache.MemorySizeCalculator
  12. import com.bumptech.glide.load.engine.executor.GlideExecutor
  13. import com.bumptech.glide.module.AppGlideModule
  14. import com.bumptech.glide.request.RequestOptions
  15. import com.fawvw.hmi.media.common.utils.LogUtil
  16. import java.io.File
  17. @GlideModule
  18. class MyAppGlideModule : AppGlideModule() {
  19.     private val TAG = "MyAppGlideModule"
  20.     //图片文件缓存 10M
  21.     private var IMAGE_CACHE_COUNT = 10 * 1024 * 1024
  22.     private val SOURCE_EXECUTOR_NAME = "source"
  23.     private val ANIMATION_EXECUTOR_NAME = "animation"
  24.     override fun applyOptions(context: Context, builder: GlideBuilder) {
  25.         super.applyOptions(context, builder)
  26.         val calculator = MemorySizeCalculator.Builder(context).build()
  27.         val defaultMemoryCacheSize = calculator.memoryCacheSize
  28.         val defaultBitmapPoolSize = calculator.bitmapPoolSize
  29.         val defaultArrayPoolSize = calculator.arrayPoolSizeInBytes
  30.         LogUtil.d(
  31.             TAG,
  32.             "defaultMemoryCacheSize: $defaultMemoryCacheSize, defaultBitmapPoolSize: $defaultBitmapPoolSize, defaultArrayPoolSize: $defaultArrayPoolSize"
  33.         )
  34.         builder.setDefaultRequestOptions(
  35.             RequestOptions().format(DecodeFormat.PREFER_RGB_565)
  36.         )
  37.         val cacheLocation = File(context.externalCacheDir, "GlideCache")
  38.         if (!cacheLocation.exists()) {
  39.             cacheLocation.mkdirs()
  40.         }
  41.         //设置glide文件缓存为10M
  42.         builder.setDiskCache {
  43.             DiskLruCacheWrapper.create(cacheLocation, IMAGE_CACHE_COUNT.toLong())
  44.         }
  45.         //设置glide内存,bitmap池,数组池砍
  46.         builder.setMemoryCache(LruResourceCache((defaultMemoryCacheSize / 4).toLong()))
  47.         builder.setBitmapPool(LruBitmapPool((defaultBitmapPoolSize / 4).toLong()))
  48.         builder.setArrayPool(LruArrayPool(defaultArrayPoolSize / 4))
  49.         //设置Source线程最大数量为1
  50.         builder.setSourceExecutor(
  51.             GlideExecutor.newSourceBuilder()
  52.                 .setThreadCount(1)
  53.                 .setName(SOURCE_EXECUTOR_NAME)
  54.                 .build()
  55.         )
  56.         //设置Animation线程最大数量为1
  57.         builder.setAnimationExecutor(
  58.             GlideExecutor.newAnimationBuilder()
  59.                 .setThreadCount(1)
  60.                 .setName(ANIMATION_EXECUTOR_NAME)
  61.                 .build()
  62.         )
  63.     }
  64.     override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
  65.         super.registerComponents(context, glide, registry)
  66.     }
  67. }
复制代码
编译过后,就可以调用GlideApp了,用于将Glide替换掉,注意别忘了添加@GlideModule注解。
总结

在进行了上面的两个定制过后,CPU和内存都有显着的降落,但是有些配置确实会导致加载速度变慢和用户体验变差,需要自己权衡。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表