glide性能优化实战

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,这是一个非常棒的设计,因为它允许你在大部分情况下一行代码搞定需求:

Glide.with(context).load(url).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

...
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
...

图片裁剪

因为缓存大小跟图片大小是有直接关系的,所以加载前最好将其裁剪为和控件大小一致,避免过大的图片造成ANR和Out Of Memory

...
.override(your size)
...

移除加载动画

Glide为了保证图片加载的过度流畅性,不显得突兀,是有默认的动画和变换的,但这也会消耗一定的性能,所以我们将它关闭

...
.dontAnimate()
.dontTransform()
...

其他

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

初步结果

都加上过后大概是这个样子

Glide.with(context).load(url).override(your size).dontAnimate().dontTransform().diskCacheStrategy(DiskCacheStrategy.RESOURCE).into(imageView);

可以从Profiler中看到加载一个list的图片时,内存和CPU都有下降。

关于Glide的AppGlideModule定制

在新版Glide中,可以通过自定义AppGlideModule来全局定义glide的设置

import android.content.Context
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.bitmap_recycle.LruArrayPool
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool
import com.bumptech.glide.load.engine.cache.DiskLruCacheWrapper
import com.bumptech.glide.load.engine.cache.LruResourceCache
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator
import com.bumptech.glide.load.engine.executor.GlideExecutor
import com.bumptech.glide.module.AppGlideModule
import com.bumptech.glide.request.RequestOptions
import com.fawvw.hmi.media.common.utils.LogUtil
import java.io.File@GlideModule
class MyAppGlideModule : AppGlideModule() {private val TAG = "MyAppGlideModule"//图片文件缓存 10Mprivate var IMAGE_CACHE_COUNT = 10 * 1024 * 1024private val SOURCE_EXECUTOR_NAME = "source"private val ANIMATION_EXECUTOR_NAME = "animation"override fun applyOptions(context: Context, builder: GlideBuilder) {super.applyOptions(context, builder)val calculator = MemorySizeCalculator.Builder(context).build()val defaultMemoryCacheSize = calculator.memoryCacheSizeval defaultBitmapPoolSize = calculator.bitmapPoolSizeval defaultArrayPoolSize = calculator.arrayPoolSizeInBytesLogUtil.d(TAG,"defaultMemoryCacheSize: $defaultMemoryCacheSize, defaultBitmapPoolSize: $defaultBitmapPoolSize, defaultArrayPoolSize: $defaultArrayPoolSize")builder.setDefaultRequestOptions(RequestOptions().format(DecodeFormat.PREFER_RGB_565))val cacheLocation = File(context.externalCacheDir, "GlideCache")if (!cacheLocation.exists()) {cacheLocation.mkdirs()}//设置glide文件缓存为10Mbuilder.setDiskCache {DiskLruCacheWrapper.create(cacheLocation, IMAGE_CACHE_COUNT.toLong())}//设置glide内存,bitmap池,数组池砍builder.setMemoryCache(LruResourceCache((defaultMemoryCacheSize / 4).toLong()))builder.setBitmapPool(LruBitmapPool((defaultBitmapPoolSize / 4).toLong()))builder.setArrayPool(LruArrayPool(defaultArrayPoolSize / 4))//设置Source线程最大数量为1builder.setSourceExecutor(GlideExecutor.newSourceBuilder().setThreadCount(1).setName(SOURCE_EXECUTOR_NAME).build())//设置Animation线程最大数量为1builder.setAnimationExecutor(GlideExecutor.newAnimationBuilder().setThreadCount(1).setName(ANIMATION_EXECUTOR_NAME).build())}override fun registerComponents(context: Context, glide: Glide, registry: Registry) {super.registerComponents(context, glide, registry)}
}

编译过后,就可以调用GlideApp了,用于将Glide替换掉,注意别忘了添加@GlideModule注解。

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/885743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最全Web自动化测试面试题

1、Selenium 中 hidden 或者是 display none 的元素是否可以定位到? 不可以。可以写 JavaScript 将标签中的 hidden 先改为 0,再进行定位元素。 2、Selenium 中如何保证操作元素的成功率?也就是说如何保证我点击的元素一 定是可以点击的&a…

PHP爬虫快速获取京东商品详情(代码示例)

在当今互联网时代,数据的重要性不言而喻。对于电商领域来说,获取商品信息是数据分析、市场研究和价格监控的基础。本文将介绍如何使用PHP编写一个简单的爬虫,以快速获取京东商品的详情信息。 1. 概述 京东是中国领先的电商平台之一&#xff…

一、HTML

一、基础概念 1、浏览器相关知识 这五个浏览器市场份额都非常大,且都有自己的内核。 什么是内核: 内核是浏览器的核心,用于处理浏览器所得到的各种资源。 例如,服务器发送图片、视频、音频的资源,浏览…

记录一次非常奇怪的MIME type of “text/html“报错

报错现象 访问指定地址,一直转圈打不开,打开游览器控制台发现有如下报错: Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of “text/html”. Strict MIME type checking i…

Windows10/11开启卓越性能模式 windows开启卓越性能电源模式 工作电脑开启卓越性能模式 电脑开启性能模式

Windows10/11开启卓越性能模式 windows开启卓越性能电源模式 工作电脑开启卓越性能模式 电脑开启性能模式 1、所要用到的激活工具2、开启电脑卓越性能模式Windows11Windows10在电源模式中选择卓越性能模式 3、将系统版本切换为 工作站版本 1、所要用到的激活工具 KMS激活工具(…

膜计算 MATLAB例程(仅例程,无背景)

膜计算的实现可以用 MATLAB 进行简单的模拟。以下是一个基础的膜计算模型的示例代码,模拟了膜内部对象的产生和转化过程。这个例子使用简单的对象和规则来演示膜计算的基本思想。 文章目录 主要概念应用领域优势与挑战代码MATLAB 膜计算示例代码代码说明运行代码总结…

Request和Response

前言 这一节主要讲的是Request和Response还有一些实例 1. 介绍 就是这两个参数 WebServlet("/demo7") public class ServletDemo7 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletExcepti…

Vue全栈开发旅游网项目(10)-设计用户模型

1.设计用户模型 文件地址:accounts/models.py 1.1 用户详细信息 内容包括:性别 手机号 年龄 生日 真实姓名 创建常量:1-男,0-女;editableFalse不许循环 class Profile(models.Model):SEX_CHOICES{(1,男),(0,女)}u…

C++初阶——vector

一、什么是vector vector是表示可变大小的数组的序列容器,就像数组一样,vector也采用连续空间来存储元素。也就是说它的访问和数组一样高效,但是它的大小是动态可变的,并且它的大小会被容器自动处理。 二、vector的构造 常用的构…

迁徙线,动态轨迹线

使用canvas结合贝塞尔曲线实现&#xff0c;效果如下 <template><div class"box"><div class"mapBox"><div class"map"><img src"/img/dataCockpit/map.png" alt"" /><div class"dot&…

SQLI LABS | Less-39 GET-Stacked Query Injection-Intiger Based

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-39/ 本关是堆…

NVM 介绍及使用指南

在日常的开发工作中&#xff0c;我们往往会遇到需要在同一台机器上同时管理多个版本的 Node.js 的情况。为了解决这个问题&#xff0c;我一个同事推荐了NVM&#xff08;Node Version Manager&#xff09;。NVM 是一个用于管理 Node.js 版本的工具&#xff0c;可以方便地在不同的…

web——[SUCTF 2019]EasySQL1——堆叠注入

这个题主要是讲述了堆叠注入的用法&#xff0c;来复现一下 什么是堆叠注入 堆叠注入&#xff1a;将多条SQL语句放在一起&#xff0c;并用分号;隔开。 1.查看数据库的名称 查看数据库名称 1;show databases; 发现有名称为ctftraining的数据库 2.对表进行查询 1;show tabl…

【ARM】MDK-烧录配置文件无权限访问

【更多软件使用问题请点击亿道电子官方网站】 1、 问题场景 客户代码编译正常、调试出现报错<Error: Flash Download failed - "Cortex-M4"> 仿真器识别正常&#xff0c;keil-Debug内显示相关信息、设备启动正常。 记录排查步骤&#xff0c;找到配置文件位…

深度解析 ICP 备案、公安备案、等保备案编号与统一社会信用代码

1. 前言 在当今数字化时代&#xff0c;各类网站和系统如雨后春笋般涌现&#xff0c;为了确保网络安全、合法运营以及用户信息保护&#xff0c;不同类型的备案工作应运而生。其中&#xff0c;ICP 备案、公安备案和等保备案尤为重要&#xff0c;它们各自对应的备案编号不仅是一串…

11个简单易用的电商购物车设计案例

文章目录 前言正文1.扁平化设计购物车2.无表格布局购物车3.美食购物车4.响应式购物车5.jQuery购物车6.动态价格更新购物车7.标签式滑动购物车8.动态商店与购物车一体化设计9.简约清爽的购物车设计10.基于Vue.js的购物车11.域名购物车 总结 前言 现在的电子商务网站&#xff0c…

turtlesim修改窗口大小;添加自己的小乌龟;

目前手边有humble版本ROS。以此为教程。其他版本以此类推 github中搜索ros&#xff0c;然后选择ros官网&#xff08;九点方阵那个图标&#xff09;。然后 在branch中&#xff0c;选择humble&#xff0c;然后复制链接。 git clone https://github.com/ros/ros_tutorials.git -…

电阻按材料分类、不同的电阻

TOC 按电阻材料工艺进行分类 3.1.线绕电阻&#xff1a; 使用高电阻率的康铜、锰铜或镍铬合金丝缠绕在陶瓷骨架&#xff08;一般采用陶瓷、塑料、涂覆绝缘层的金属骨架&#xff09;上制作而成的。玻璃釉绕线电阻表面被覆一层玻璃釉&#xff1b;涂漆线绕电阻表面被覆一层保护有…

spark的学习-06

SparkSQL读写数据的方式 1&#xff09;输入Source 方式一&#xff1a;给定读取数据源的类型和地址 spark.read.format("json").load(path) spark.read.format("csv").load(path) spark.read.format("parquet").load(path) 方式二&#xff1a…

react-markdown内容宽度溢出和换行不生效问题

情景复现&#xff1a; 解决办法&#xff0c;添加样式进行限制 /* index.css */ .markdown-container {word-break: break-word; /* 强制长单词断行 */white-space: pre-wrap; /* 保留空白符序列&#xff0c;但是正常地进行换行 */overflow-wrap: break-word; /* 在长单词或…