Android App开发之利用Glide实现图片的三级缓存Cache讲解及实战(附源码 超详细必看 简单易懂)

news2025/7/8 16:14:05

需要图片集和源码请点赞关注收藏后评论区留言~~~

一、利用Glide实现图片的三级缓存

图片加载框架之所以高效,是因为它不但封装了访问网络的步骤,而且引入了三级缓存的机制。具体来说,是先到内存中查找图片,找到了就直接显示内存图片,没找到就去磁盘中查找图片,在磁盘中找到就直接显示磁盘图片,最后没找到的话再去请求网络。如此便形成了内存-磁盘-网络的三级缓存。(学过计算机组成原理或操作系统的同学应该对这个思想比较熟悉~~~)

对于Glide而言,默认已经开启了三级缓存机制 ,当然也可以根据实际情况另行调整。

 请求建造器RequestBuilder有以下常用 方法

1:placeholder 设置加载开始的占位图

2:error  设置发生错误的提示图

3:override  设置图片的尺寸

4:diskCacheStrategy  设置指定的缓存策略

5:skipMemoryCache  设置是否跳过内存缓存

6:disallowHardwareConfig  关闭硬件加速

7:fitCenter 保持图片的宽高比例并居中显示

8:centerCrop  保持图片的宽高比例 使它充满视图

9:circleCrop 展示圆形剪裁后的图片

另外Glide允许播放加载过程的渐变动画,让图片从迷雾中逐渐变得清晰 有助于提高用户体验

效果如下

点击不同的按钮以及下拉框选项可呈现不同的效果以及缓存策略

 

 

 

 

 代码如下

Java类

package com.example.chapter14;

import android.annotation.SuppressLint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Spinner;

import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;

@SuppressLint("CheckResult")
public class GlideCacheActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {
    private ImageView iv_network;
    private String mImageUrl = "http://b68.photo.store.qq.com/psu?/0664e98e-f40a-4899-b6d6-4f4f1d94ef3c/4qBaAk.83Z9Zw9XIZUwtV**iFrAWIquow4FP0aIIQSc!/b/YWWPjCjyCgAAYra8lShRCwAA";
    private CheckBox ck_seize; // 声明一个复选框对象。是否启用占位图
    private CheckBox ck_error; // 声明一个复选框对象。是否启用出错图
    private CheckBox ck_original; // 声明一个复选框对象。是否加载原图片
    private CheckBox ck_transition; // 声明一个复选框对象。是否呈现渐变动画
    private int mCacheStrategy; // 缓存策略的类型

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_glide_cache);
        iv_network = findViewById(R.id.iv_network);
        ck_seize = findViewById(R.id.ck_seize);
        ck_error = findViewById(R.id.ck_error);
        ck_original = findViewById(R.id.ck_original);
        ck_transition = findViewById(R.id.ck_transition);
        ck_seize.setOnCheckedChangeListener(this);
        ck_error.setOnCheckedChangeListener(this);
        ck_original.setOnCheckedChangeListener(this);
        ck_transition.setOnCheckedChangeListener(this);
        initStrategySpinner(); // 初始化缓存策略的下拉框
    }

    // 初始化缓存策略的下拉框
    private void initStrategySpinner() {
        ArrayAdapter<String> modeAdapter = new ArrayAdapter<String>(this,
                R.layout.item_select, strategyArray);
        Spinner sp_cache_strategy = findViewById(R.id.sp_cache_strategy);
        sp_cache_strategy.setPrompt("请选择缓存策略");
        sp_cache_strategy.setAdapter(modeAdapter);
        sp_cache_strategy.setSelection(0);
        sp_cache_strategy.setOnItemSelectedListener(new StrategySelectedListener());
    }

    private String[] strategyArray = {"自动选择缓存策略", "不缓存图片", "只缓存原始图片", "只缓存压缩后的图片", "同时缓存原图和压缩图片"};

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        showNetworkImage(); // 加载并显示网络图片
    }

    class StrategySelectedListener implements AdapterView.OnItemSelectedListener {
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            mCacheStrategy = arg2;
            showNetworkImage(); // 加载并显示网络图片
        }

        public void onNothingSelected(AdapterView<?> arg0) {
        }
    }

    // 加载并显示网络图片
    private void showNetworkImage() {
        // 构建一个加载网络图片的建造器
        RequestBuilder<Drawable> builder = Glide.with(this).load(mImageUrl);
        RequestOptions options = new RequestOptions(); // 创建Glide的请求选项
//        options.disallowHardwareConfig(); // 关闭硬件加速,防止过大尺寸的图片加载报错
        options.skipMemoryCache(true); // 是否跳过内存缓存(但不影响硬盘缓存)
        options.override(300, 200); // 设置图片的宽高
        if (ck_seize.isChecked()) { // 勾选了占位图
            options.placeholder(R.drawable.load_default); // 设置加载开始的占位图
        }
        if (ck_error.isChecked()) { // 勾选了出错图
            options.error(R.drawable.load_error); // 设置发生错误的提示图
        }
        if (ck_original.isChecked()) { // 勾选了原始图
            options.override(Target.SIZE_ORIGINAL); // 展示原始图片
        }
        if (ck_transition.isChecked()) { // 勾选了渐变动画
            builder.transition(DrawableTransitionOptions.withCrossFade(3000)); // 设置时长3秒的渐变动画
        }
        if (mCacheStrategy == 0) { // 自动选择缓存策略
            options.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC); // 设置指定的缓存策略
        } else if (mCacheStrategy == 1) { // 不缓存图片
            options.diskCacheStrategy(DiskCacheStrategy.NONE); // 设置指定的缓存策略
        } else if (mCacheStrategy == 2) { // 只缓存原始图片
            options.diskCacheStrategy(DiskCacheStrategy.DATA); // 设置指定的缓存策略
        } else if (mCacheStrategy == 3) { // 只缓存压缩后的图片
            options.diskCacheStrategy(DiskCacheStrategy.RESOURCE); // 设置指定的缓存策略
        } else if (mCacheStrategy == 4) { // 同时缓存原始图片和压缩图片
            options.diskCacheStrategy(DiskCacheStrategy.ALL); // 设置指定的缓存策略
        }
        // 在图像视图上展示网络图片。apply方法表示启用指定的请求选项
        builder.apply(options).into(iv_network);
    }

}

XML文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:orientation="horizontal">

        <CheckBox
            android:id="@+id/ck_seize"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="left|center"
            android:text="是否启用占位图"
            android:textColor="#000000"
            android:textSize="17sp" />

        <CheckBox
            android:id="@+id/ck_error"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="left|center"
            android:text="是否启用出错图"
            android:textColor="#000000"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:orientation="horizontal">

        <CheckBox
            android:id="@+id/ck_original"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="left|center"
            android:text="是否加载原图片"
            android:textColor="#000000"
            android:textSize="17sp" />

        <CheckBox
            android:id="@+id/ck_transition"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="left|center"
            android:text="是否呈现渐变动画"
            android:textColor="#000000"
            android:textSize="17sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="缓存策略:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Spinner
            android:id="@+id/sp_cache_strategy"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:spinnerMode="dialog" />

    </LinearLayout>

    <ImageView
        android:id="@+id/iv_network"
        android:layout_width="match_parent"
        android:layout_height="250dp" />
</LinearLayout>

创作不易 觉得有帮助请点赞关注收藏~~~

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

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

相关文章

国内访问Github超级慢?那是你没有用我这个脚本。直接起飞。

导语 之前很多朋友咨询过国内访问Github较慢的问题&#xff0c;然后我一般让他们自己去知乎上找攻略&#xff0c;但今天我才发现网上竟然没有一个一键配置的脚本&#xff0c;一般都需要我们跟着教程一步步地去做才行。这也太麻烦了&#xff0c;于是自己动手写了个脚本&#xf…

2-1 C++类的转换函数与禁止隐士转换(explicit)

1. 转换函数与explicit关键字 1.1 转换函数 下述代码的第5行operator double()即是一个转换函数&#xff0c;通过这个函数&#xff0c;编译器可以在需要的情况下&#xff0c;直接将Fraction类型的对象转换为double类型。这个函数有两个特点&#xff1a;首先因为转换函数的返回…

FFplay文档解读-50-多媒体过滤器四

32.21 showspectrumpic 将输入音频转换为单个视频帧&#xff0c;表示音频频谱。 过滤器接受以下选项&#xff1a; size&#xff0c;s指定输出的视频大小。 有关此选项的语法&#xff0c;请查阅&#xff08;ffmpeg-utils&#xff09;视频大小语法。 默认值为4096x2048。 mod…

Spring Boot入门必会(基本介绍+依赖管理+自动装配)

目录 一.基础入门 1.Spring Boot 是什么? 2.SpringBoot 快速入门 2.1完成步骤 2.2快速入门小结 3.Spring SpringMVC SpringBoot 的关系 3.1梳理关系 3.2如何理解 -约定优于配置 二.依赖管理和自动配置 1.依赖管理 1.1 什么是依赖管理 1.2 修改自动仲裁/默认版本号 …

论文阅读-Federated Social Recommendation with Graph NeuralNetwork

基于图神经网络的联邦社交推荐 1. 引言 因此&#xff0c;针对社交推荐任务&#xff0c;我们设计了一个联邦学习推荐系统&#xff0c;该系统具有异构性、个性化和隐私保护要求&#xff0c;具有一定的挑战性。为此&#xff0c;设计了一个基于图神经网络(FeSoG)的联邦社交推荐框…

【RHCE】ansible的简单配置

目录 使用静态清单文件指定受管主机 定义主机清单 定义方式 使用静态主机清单指定受管主机&#xff08;默认&#xff09; 验证清单 第一种方式 第二种方式&#xff08;图表形式显示&#xff09; 选择主机和组&#xff1a; 1>匹配所有主机 2>匹配指定的主机或者主…

二叉树与树、森林之间的转换

关于树的概念 树可以称为特殊的森林 &#xff0c; 其中二叉树是树中一些节点度数最大为2 &#xff0c;并且分左右孩子的树 ● 二叉树很重要 • 结构简单 • 存储效率高 • 运算算法相对简单 • 任何森林、树都可以转换成二叉树 ● 讨论 • 二叉树 度为2 的树 ? 答: 树的度就是…

官方盘点 .NET 7 新功能

.NET 7 为C# 11/F# 7、.NET MAUI、ASP.NET Core/Blazor、Web API、WinForms、WPF 等应用程序带来了更高的性能和新功能。使用 .NET 7&#xff0c;您还可以轻松地将 .NET 7 项目容器化&#xff0c;在 GitHub 操作中设置 CI/CD 工作流&#xff0c;并实现云原生可观察性。欢迎下载…

java之Fork/Join框架

文章目录前言工作窃取算法Fork/Join框架的设计Fork/Join框架的异常处理Fork/Join框架的实现原理总结前言 Fork/Join框架是java7提供的一个用于执行并行任务的框架&#xff0c;是一个把大部分任务分割成若干个小任务&#xff0c;最终汇总每个小任务结果后&#xff0c;得到大任务…

4进程地址空间

文章目录前言1. 概念引入2. CPU和物理内存关系3.何为进程地址空间4. 为什么存在地址空间?前言 本节主要是讲解进程地址空间,区分和物理内存地址空间的差别,并且向读者解释四个疑问: 怎样验证地址空间的排布; 进程地址空间是什么; 进程地址空间和物理内存之间的关系; 为什么要…

[附源码]java毕业设计基于web的球类体育馆预定系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

数据链路层(2层 Data Link Layer)

1、数据链路层属于2层 2、传输单元&#xff1a;帧 帧格式&#xff1a; 802.3 有线网卡 802.11 无线网卡&#xff0c;无线路由器都支持802.11 802开头的都是国际标准&#xff0c;是由IEEE国际学术组织制定的标准 3、帧结构的构成&#xff1a;MAC子层&#xff08;帧头&…

MySQL表的增删改查(进阶)

目录1.数据库约束1.1约束类型1.2 NULL约束1.3 UNIQUE&#xff1a;唯一约束1.4 PRIMARY KEY: 主键约束1.5 DEFAULT&#xff1a;默认值约束1.6 FOREIGN KEY&#xff1a;外键约束2. 表的设计3. 新增4. 查询4.1 聚合查询4.1.2 GROUP BY子句4.2 联合查询4.2.1内连接4.2.2外连接4.2.3…

2022 第十四届蓝桥杯模拟赛第一期(题解与标程)

第十四届蓝桥杯模拟赛第一期1. 二进制位数问题描述答案提交参考答案2. 晨跑问题描述答案提交参考答案3. 调和级数问题描述答案提交参考答案程序验证4. 山谷问题描述答案提交参考答案5. 最小矩阵问题描述答案提交参考答案6. 核酸日期问题描述输入格式输出格式样例输入样例输出评…

项目风险管理的5大关键点,你做了几点?

1、全方位科学分析项目风险 为了提高项目抗风险能力&#xff0c;我们需要对项目风险进行科学全面的分析。一般我们从3个维度对风险进行科学分析&#xff1a;影响的严重性、发生的可能性、产生的影响性。 根据风险或机会对项目的影响程度&#xff0c;一般我们会从三个维度将其划…

javascript大作业《web课程设计》用html做一个期末作业网站,梅西足球体育网页,css

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

STING 与 cGAS的结合导致TBK1 激酶募集和活化

来自细菌或病毒的核酸在受感染的细胞中会产生强效的免疫反应&#xff0c;而病原体衍生核酸的检测是宿主感知感染并启动保护性免疫反应的核心策略。cGAS (Cyclic GMP-AMP synthase) 是一种双链 DNA 传感器&#xff0c;可催化 cGAMP&#xff08;cyclic GMP-AMP&#xff09;的合成…

二级导航栏

简介&#xff1a;本文通过HTML与CSS相集合的方式&#xff0c;来实现二级导航菜单。 HTML构建骨架 <body><ul class"nav1"><li>水果<ul class"nav2"><li>苹果</li><li>香梨</li><li>火龙果</li…

前端CSS射门动画-为梅西最后一届世界杯加油

☆ 距离2022卡塔尔世界杯只有6天时间了&#xff0c;众多球星我喜欢梅西和奥乔亚。 ☆ 我们不能到现场去&#xff0c;只能手中的代码自娱自乐一下&#xff0c;就当为梅西加油了。这是梅西最后一届世界杯了。 梅西给我的感觉&#xff0c;踢球足够利落干净&#xff0c;你不会从他的…

AI遮天传 ML/DL-感知机

感知机的出现是人工智能发展史一大重要里程碑&#xff0c;其后才诞生了&#xff1a;多层感知机、卷积神经网络等一系列的经典网络模型。 在我看来&#xff0c;它虽然是深度学习领域的一大开端&#xff0c;但本身解决的只是线性二分类问题&#xff0c;它本身与机器学习经典模型线…