当前位置: 首页 > news >正文

从网络到缓存:在Android中高效管理图片加载

文章目录

    • 在Android应用中实现图片缓存和下载
      • 项目结构
        • 使用
      • 代码解析
      • 关键功能解析
        • 1. 图片加载方法
        • 2. 下载图片
        • 3. 保存图片到缓存
        • 4. 文件名提取
      • 总结

首先我们需要在配置AndroidManifest.xml里面添加

<uses-permission android:name="android.permission.INTERNET" />

在Android应用中实现图片缓存和下载

在现代移动应用开发中,用户体验至关重要,特别是在图像加载方面。为了提高应用的响应速度和减少网络流量,我们通常采用缓存机制来存储下载的图片。本文将介绍如何在Android中实现一个简单的图片缓存加载器,允许从网络下载图片并缓存到本地。

项目结构

我们将构建一个名为 ImageCacheLoader 的类,该类负责从URL加载图片,并首先检查本地缓存。如果缓存不存在,则从网络下载图片。

使用
package com.example.dowhttppic;import android.os.Bundle;import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private ImageView imageView;private ImageCacheLoader imageCacheLoader;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);imageView = findViewById(R.id.imageView);// 初始化 ImageCacheLoaderimageCacheLoader = new ImageCacheLoader(this);// 加载图片String imageUrl = "图片链接";imageCacheLoader.loadImage(imageUrl, imageView);}
}

代码解析

package com.example.dowhttppic;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.widget.ImageView;import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;public class ImageCacheLoader {private Context context;private Handler handler = new Handler(); // 用于处理UI线程更新// 构造函数,接收上下文public ImageCacheLoader(Context context) {this.context = context;}// 公共方法:加载图片,首先从缓存读取,如果没有则通过网络下载public void loadImage(final String url, final ImageView imageView) {// 获取缓存目录File cacheDir = context.getCacheDir();String fileName = getFileNameFromUrl(url);final File imageFile = new File(cacheDir, fileName);// 如果本地有缓存,直接加载本地图片if (imageFile.exists()) {Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());imageView.setImageBitmap(bitmap);} else {// 启动线程下载图片并缓存new Thread(new Runnable() {@Overridepublic void run() {Bitmap bitmap = downloadImage(url);if (bitmap != null) {saveImageToCache(imageFile, bitmap);// 更新UI,需在主线程中执行handler.post(new Runnable() {@Overridepublic void run() {imageView.setImageBitmap(bitmap);}});} else {// 超时或下载失败时显示默认图片handler.post(new Runnable() {@Overridepublic void run() {imageView.setImageResource(R.drawable.no_image_dow_http);}});}}}).start();}}// 从网络下载图片,添加超时机制private Bitmap downloadImage(String urlString) {Bitmap bitmap = null;try {URL url = new URL(urlString);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setConnectTimeout(5000); // 设置连接超时为5秒connection.setReadTimeout(5000); // 设置读取超时为5秒connection.connect();int responseCode = connection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = connection.getInputStream();bitmap = BitmapFactory.decodeStream(inputStream);inputStream.close();}} catch (Exception e) {e.printStackTrace();}return bitmap;}// 将下载的图片保存到本地缓存private void saveImageToCache(File imageFile, Bitmap bitmap) {try {OutputStream outputStream = new FileOutputStream(imageFile);bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);outputStream.flush();outputStream.close();} catch (Exception e) {e.printStackTrace();}}// 根据URL提取文件名private String getFileNameFromUrl(String url) {return url.substring(url.lastIndexOf("/") + 1);}
}

关键功能解析

1. 图片加载方法

loadImage 方法是该类的核心,它负责加载指定URL的图片。首先,它尝试从本地缓存读取图片,如果缓存存在,则直接使用缓存的图片;如果不存在,则启动一个新线程下载图片。

public void loadImage(final String url, final ImageView imageView) {File cacheDir = context.getCacheDir();String fileName = getFileNameFromUrl(url);final File imageFile = new File(cacheDir, fileName);if (imageFile.exists()) {Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());imageView.setImageBitmap(bitmap);} else {new Thread(new Runnable() {@Overridepublic void run() {Bitmap bitmap = downloadImage(url);if (bitmap != null) {saveImageToCache(imageFile, bitmap);handler.post(new Runnable() {@Overridepublic void run() {imageView.setImageBitmap(bitmap);}});} else {handler.post(new Runnable() {@Overridepublic void run() {imageView.setImageResource(R.drawable.no_image_dow_http);}});}}}).start();}
}
2. 下载图片

downloadImage 方法使用 HttpURLConnection 从给定URL下载图片。它设置了连接和读取的超时,以避免长时间等待。

private Bitmap downloadImage(String urlString) {Bitmap bitmap = null;try {URL url = new URL(urlString);HttpURLConnection connection = (HttpURLConnection) url.openConnection();connection.setConnectTimeout(5000);connection.setReadTimeout(5000);connection.connect();int responseCode = connection.getResponseCode();if (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = connection.getInputStream();bitmap = BitmapFactory.decodeStream(inputStream);inputStream.close();}} catch (Exception e) {e.printStackTrace();}return bitmap;
}
3. 保存图片到缓存

saveImageToCache 方法将下载的图片以PNG格式保存到应用的缓存目录中。

private void saveImageToCache(File imageFile, Bitmap bitmap) {try {OutputStream outputStream = new FileOutputStream(imageFile);bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);outputStream.flush();outputStream.close();} catch (Exception e) {e.printStackTrace();}
}
4. 文件名提取

getFileNameFromUrl 方法从图片URL中提取文件名,以便在缓存中使用。

private String getFileNameFromUrl(String url) {return url.substring(url.lastIndexOf("/") + 1);
}

总结

通过实现 ImageCacheLoader 类,我们成功地创建了一个简单的图片加载和缓存机制。这种方法不仅减少了网络流量,还提高了应用的响应速度和用户体验。在实际应用中,你可以根据需要进一步扩展该类,例如添加图片加载动画、处理更多的错误情况,或是实现更复杂的缓存策略。

相关文章:

从网络到缓存:在Android中高效管理图片加载

文章目录 在Android应用中实现图片缓存和下载项目结构使用 代码解析关键功能解析1. 图片加载方法2. 下载图片3. 保存图片到缓存4. 文件名提取 总结 首先我们需要在配置AndroidManifest.xml里面添加 <uses-permission android:name"android.permission.INTERNET" …...

【数据结构】链表详解:数据节点的链接原理

链表&#xff08;Linked List&#xff09;是一种基础的数据结构&#xff0c;是程序设计中用来存储数据的典型方法之一。链表特别适合插入和删除操作频繁的场景&#xff0c;是了解数据结构和算法的基础。本文将从零开始&#xff0c;带大家了解链表的底层原理、类型&#xff08;单…...

使用AWS Redshift从AWS MSK中读取数据

Amazon Redshift 流式摄取的目的是简化将流式数据直接从流式服务摄取到 Amazon Redshift 或 Amazon Redshift Serverless 的过程。 官方文档[1]中有详细步骤。用unauthenticated, IAM 的方式均可以进行连接&#xff0c;只不过使用的是不同端口&#xff1a;9092或者9098 [1] h…...

从0开始学统计-数据类别与测量层次

数据分析前&#xff0c;我们首先要弄清楚数据的分类。数据并不仅仅是一堆数字和文字&#xff0c;它们实际上代表了我们看待事物属性的不同视角。从最宽泛的角度出发&#xff0c;我们可以将数据划分为定量&#xff08;比如用数字表示&#xff09;或者定性&#xff08;例如&#…...

使用AIM对SAP PO核心指标的自动化巡检监控

一、背景 由于SAP PO系统维护成本较高&#xff0c;各类型异常报错等都需要人员进行时刻监控和响应&#xff0c;遂由AIM平台进行自动化巡检SAP PO的各指标&#xff0c;然后告警通知用户&#xff0c;节省维护成本和提高工作效率 二、核心指标监控 SAP PO失败消息 适用于S…...

C++——unordered_map和unordered_set的封装

unordered_map和unordered_set的底层结构用到的都是在哈希表模拟实现中的哈希桶的实现方式&#xff0c;哈希桶的具体实现我已经在哈希表的模拟实现里做过详细的介绍&#xff0c;这边会引用里面的代码进行改造和封装&#xff0c;同时为了方便操作&#xff0c;同样我采用二倍扩容…...

微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析

微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析 目录 微信小程序scroll-view吸顶css样式化表格的表头及iOS上下滑动表头的颜色覆盖、z-index应用及性能分析 1、iOS在scroll-view内部上下滑动吸顶的现象 正常的上下滑动吸顶…...

【高中数学】数列

等差数列前 n n n 项和性质 公式一&#xff1a; S n n ( a 1 a n ) 2 S_n\frac{n(a_1a_n)}{2} Sn​2n(a1​an​)​ 公式二&#xff1a; S n n a 1 n ( n − 1 ) 2 d S_nna_1\frac{n(n-1)}{2}d Sn​na1​2n(n−1)​d 性质1&#xff1a;等差数列中依次 k k k 项之和 S …...

数字媒体技术基础:AMF(ACES 元数据文件 )

在现代电影和电视制作中&#xff0c;色彩管理变得越来越重要。ACES&#xff08;Academy Color Encoding System&#xff0c;美国电影艺术与科学学院颜色编码系统&#xff09;是一个广泛采用的色彩管理和交换系统&#xff0c;旨在解决不同设备、软件和工作流程之间的色彩不一致问…...

Apache Dubbo (RPC框架)

本文参考官方文档&#xff1a;Apache Dubbo 1. Dubbo 简介与核心功能 Apache Dubbo 是一个高性能、轻量级的开源Java RPC框架&#xff0c;用于快速开发高性能的服务。它提供了服务的注册、发现、调用、监控等核心功能&#xff0c;以及负载均衡、流量控制、服务降级等高级功能。…...

LeetCode 3226. 使两个整数相等的位更改次数

. - 力扣&#xff08;LeetCode&#xff09; 题目 给你两个正整数 n 和 k。你可以选择 n 的 二进制表示 中任意一个值为 1 的位&#xff0c;并将其改为 0。 返回使得 n 等于 k 所需要的更改次数。如果无法实现&#xff0c;返回 -1。 示例 1&#xff1a; 输入&#xff1a; n …...

面试经典 150 题:189、383

189. 轮转数组 【参考代码】 class Solution { public:void rotate(vector<int>& nums, int k) {int size nums.size();if(1 size){return;}vector<int> temp(size);//k k % size;for(int i0; i<size; i){temp[(i k) % size] nums[i];}nums temp; }…...

Python模拟真人动态生成鼠标滑动路径

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…...

如何压缩pdf文件的大小?5分钟压缩pdf的方法推荐

如何压缩pdf文件的大小&#xff1f;在现代办公和学习中&#xff0c;PDF文件因其稳定性和广泛的兼容性被广泛使用。然而&#xff0c;随着文件内容的增多&#xff0c;制作好的PDF文件常常变得过大&#xff0c;给使用带来了诸多不便。无论是电子邮件附件的发送&#xff0c;还是在线…...

【SQL】[2BP01] ERROR: cannot drop table course because other objects depend on it

问题描述 在尝试执行以下SQL语句时&#xff0c;发生错误。 DROP TABLE Course RESTRICT;执行以上语句后&#xff0c;系统返回了一个错误提示&#xff1a; [2BP01] ERROR: cannot drop table course because other objects depend on it 详细&#xff1a;constraint sc_cno_…...

gbase8s之spring框架用druid中间件报语法错误

spring框架 调用druid中间件 时报这个错&#xff1a; MetaDataAccessException: Could not get Connection for extracting meta-data; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception …...

【网络安全】|nessus使用

1、扫描结果分析&#xff1a; Sev&#xff1a;漏洞的严重性级别 CVSS&#xff1a;量化漏洞严重性的标准&#xff0c;通过计算得出一个分数&#xff0c;分数越高表示漏洞越严重。 VPR&#xff1a;基于风险的评分系统&#xff0c;帮助组织优先处理风险最高的漏洞。 EPSS&#xf…...

CSRA2的LINUX操作系统24年11月2日上午上课笔记

几个查找命令&#xff1a; .whereis:查看文件的路径,查看可执行文件的路径&#xff0c;一级相应文档路径。 .which:查看系统可执行的文件的路径&#xff0c;以及命令的别名等信息 .local&#xff1a;他会将linux中的所有文件的路径信息保存到数据库中&#xff0c;在数据库中查…...

通过分解质因数求若干个数的最小公倍数

求最小公倍数的常规方法回顾 暴力枚举法 long long work(long long a,long long b) {for(long long imax(a,b);;i)if(i%a0&&i%b0)return i; }大数翻倍法 long long work(long long a,long long b) {if(a<b) swap(a,b);for(long long ia;;ia) // i 是 a 的倍数&#…...

数据库三范式(1NF、2NF、3NF)

1NF&#xff08;第一范式&#xff09; 定义&#xff1a;确保每一列都是原子值&#xff0c;即是不可分割的基础数据项。 所谓第一范式&#xff08;1NF&#xff09;是指在关系模型中&#xff0c;对于添加列的一个规范要求&#xff0c;所有的列都 应该是原子性的&#xff0c;即数…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

GraphRAG优化新思路-开源的ROGRAG框架

目前的如微软开源的GraphRAG的工作流程都较为复杂&#xff0c;难以孤立地评估各个组件的贡献&#xff0c;传统的检索方法在处理复杂推理任务时可能不够有效&#xff0c;特别是在需要理解实体间关系或多跳知识的情况下。先说结论&#xff0c;看完后感觉这个框架性能上不会比Grap…...

GeoServer发布PostgreSQL图层后WFS查询无主键字段

在使用 GeoServer&#xff08;版本 2.22.2&#xff09; 发布 PostgreSQL&#xff08;PostGIS&#xff09;中的表为地图服务时&#xff0c;常常会遇到一个小问题&#xff1a; WFS 查询中&#xff0c;主键字段&#xff08;如 id&#xff09;莫名其妙地消失了&#xff01; 即使你在…...