安卓之缓存的应用场景以及各种技术优劣分析

文章摘要

        本文主要探讨了安卓开发中的缓存技术及其应用场景,通过分析几种常见的缓存技术,包括内存缓存、磁盘缓存和网络缓存,阐述了它们的优点和缺点。此外,本文还提供了相应的代码示例,以帮助读者更好地理解这些缓存技术的实现方式。

一、引言

        在当今的应用程序开发中,缓存技术已成为提高应用程序性能和响应速度的重要手段。安卓作为全球最流行的移动操作系统之一,其应用程序的缓存技术也备受关注。本文将重点分析安卓开发中的缓存技术及其应用场景,并探讨各种缓存技术的优劣。

二、应用场景

2.1、图片加载与显示

        当用户滚动社交媒体时间线或浏览商品列表时,通过内存缓存(如LruCache)和磁盘缓存(如DiskLruCache或使用Picasso、Glide等库的内置缓存机制)保存已加载过的图片资源,避免重复从服务器下载。

2.2、API响应数据缓存

        对于不频繁变动的数据(如新闻详情、用户信息等),在网络请求结果成功获取后将其存储在本地数据库或文件系统中作为缓存,当用户再次访问同一内容时,首先检查缓存并优先展示,减少不必要的网络交互。

2.3、离线内容访问

        为用户提供离线阅读或观看功能,例如将文章、视频或其他内容预先缓存到设备上,让用户在网络连接不稳定或无网络环境下仍能正常访问。

2.4、搜索历史记录

        在搜索框中缓存用户的搜索关键词,实现快速联想提示或历史查询记录回显。

2.5、用户配置和偏好设置

        使用SharedPreferences或者SQLite数据库缓存用户的个性化设置,确保即使在离线状态下也能维持一致的界面风格和操作习惯。

2.6、地图数据预加载

        地图应用可以提前下载并缓存附近区域的地图数据、POI信息等,提高地图浏览和导航的流畅度。

2.7、应用程序启动速度优化

        首次打开应用时加载的基础数据可以被缓存起来,后续启动时直接读取缓存数据,加快启动速度。

2.8、网络请求的HTTP缓存

        根据HTTP协议标准,利用OkHttp等网络库提供的HTTP缓存功能,根据响应头中的Cache-Control、ETag等字段自动处理缓存策略,从而减少不必要的网络请求。

2.9、游戏资源加载

        游戏中的大量静态资源如图像、音频、关卡数据等可以在首次加载后存储在本地缓存,后续游戏过程直接读取本地资源,提高游戏运行效率。

        以上场景只是缓存在Android应用中的一部分应用示例,实际上,任何需要临时存储、快速访问、降低IO开销的情况都可能用到缓存技术。

三、缓存技术优劣分析

3.1、内存缓存

        在Android应用开发中,内存缓存主要指的是将数据存储在设备RAM中的缓存机制,以实现快速访问和减少重复计算或网络请求的目的。常见的内存缓存主要包括以下几种类型:

        LruCache:LruCache 是一种基于 LRU(Least Recently Used,最近最少使用)算法的缓存实现,用于存储可回收的对象。它被用来替代 HashMap 作为 View 的缓存。LruCache 能够根据对象的引用情况进行回收,当缓存满时,会自动删除最久未使用的对象。

        SoftReference / WeakReference缓存:Java中提供了软引用(SoftReference)和弱引用(WeakReference)来间接实现内存缓存。当系统内存紧张时,这些引用关联的对象可能被垃圾回收器清理掉,但它们的生存期比强引用更短,适合用于缓存非关键性资源。

        自定义数据结构缓存:开发者可以根据需求使用HashMap、LinkedHashMap等数据结构自行构建内存缓存系统,并实现缓存淘汰策略,如LFU(Least Frequently Used)、FIFO(First In First Out)等。

        Bitmap Pool缓存:在处理图像资源时,Android中有专门针对Bitmap对象的内存缓存池,如 Glide 和 Picasso 库内部就实现了这样的功能,通过复用已解码的Bitmap来节省内存开销。

        View Holder缓存:在RecyclerView或其他列表组件中,ViewHolder模式也是一种内存缓存形式,它缓存了已经创建过的视图组件实例,避免每次滚动列表时频繁地重新创建和绑定视图。

3.1.1、优点

        速度快,数据存取效率高

3.1.2、缺点

        受限于内存大小,一旦内存不足,缓存的数据可能会被清除。

        适用于小量数据的缓存。

3.2、磁盘缓存

        磁盘缓存是一种持久化存储机制,用于将数据保存在设备的内部或外部存储空间中。相比于内存缓存,磁盘缓存可以存储更多的数据且不受进程生命周期影响,但读写速度较慢。

        磁盘缓存主要包括以下几种形式:

        文件系统缓存:最简单的一种缓存方式,直接将数据写入文件系统。简单易用,但不易管理,容易造成文件碎片化,影响性能。

        数据库缓存:使用SQLite等数据库来存储缓存数据。可以实现数据持久化,易于管理,但需要额外的数据库操作,性能相对较低。

        第三方缓存库:如Google的DiskLruCache等。易于使用和管理,提供丰富的API和功能,但可能需要引入第三方依赖。

3.2.1、优点

        存储空间大,可以存储大量数据,数据持久化;

3.2.2、缺点

        速度较慢,因为涉及到磁盘读写操作,需要额外的磁盘空间。

3.3、网络缓存

3.3.1、优点

        灵活配置缓存策略,例如设置缓存有效期、缓存大小等,可以实现网络请求的优化,减少对网络的依赖;

3.3.2、缺点

        需要额外的配置和代码实现,对于非网络请求的场景可能不太适用。

四、代码示例

4.1、LruCache

        以下是一个使用LruCache实现图片内存缓存的示例代码:

import android.graphics.Bitmap;
import android.util.LruCache;public class ImageMemoryCache {private LruCache<String, Bitmap> mMemoryCache;public ImageMemoryCache(int maxSize) {// 初始化LruCache,设置最大缓存大小为maxSize(单位:字节)int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);int cacheSize = maxMemory / 8; // 使用总内存的1/8作为缓存大小mMemoryCache = new LruCache<>(cacheSize) {@Overrideprotected int sizeOf(String key, Bitmap value) {// 计算单个条目的大小(这里假设Bitmap占用的内存按像素点数计算)return value.getRowBytes() * value.getHeight() / 1024;}};}public void addBitmapToMemoryCache(String key, Bitmap bitmap) {if (getBitmapFromMemCache(key) == null) {mMemoryCache.put(key, bitmap);}}public Bitmap getBitmapFromMemCache(String key) {return mMemoryCache.get(key);}
}

4.2、SQLite

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class CacheDatabaseHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "cache.db";private static final int DATABASE_VERSION = 1;public CacheDatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {String createTable = "CREATE TABLE IF NOT EXISTS CacheData (_id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT, value TEXT)";db.execSQL(createTable);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}public void put(String key, String value) {SQLiteDatabase db = this.getWritableDatabase();ContentValues contentValues = new ContentValues();contentValues.put("key", key);contentValues.put("value", value);db.insert("CacheData", null, contentValues);db.close();}public String get(String key) {String value = null;SQLiteDatabase db = this.getReadableDatabase();Cursor cursor = db.query("CacheData", new String[]{"value"}, "key = ?", new String[]{key}, null, null, null);if (cursor.moveToFirst()) {value = cursor.getString(0);}if(cursor != null) cursor.close();db.close();return value;}
}

4.3、OkHttp

在build.gradle中引入依赖。

implementation 'com.squareup.okhttp3:okhttp:4.9.0'import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;public class OkHttpCache {public OkHttpCache(File cacheDirectory, Long cacheSize) {// 创建一个OkHttpClient实例并配置缓存大小和过期时间等参数。OkHttpClient client = new OkHttpClient.Builder().cache(new Cache(cacheDirectory, cacheSize)) // 指定缓存目录和大小限制。.build();//使用OkHttp发送HTTP请求时,会自动使用配置的缓存机制进行数据获取和处理。Request request = new Request.Builder().url("http://example.com") // 设置请求的URL。.build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {// 处理请求失败的情况。}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (!response.isSuccessful()) {throw new IOException("Unexpected code " + response);} else {// 处理响应数据,可以从response.body()获取响应体。}}});}
}

、结论

        在安卓开发中,选择合适的缓存技术对于提高应用程序性能和响应速度至关重要。内存缓存适用于小量数据的快速存取;磁盘缓存适用于大量数据的持久化存储;而网络缓存则适用于网络请求的优化。在实际开发中,应根据具体需求选择合适的缓存技术,并充分考虑其优缺点。通过合理配置和应用缓存策略,可以提高应用程序的性能和用户体验。

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

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

相关文章

Prepar3D设置全屏显示设置方法

一、 基础设置 当视景软件显示的屏幕超过一个的时候&#xff0c;需要将多个显示屏幕在设置->屏幕设置->多显示器这里设置为扩展这些显示器。 二、全屏方法说明 一般情况只需要设置了多屏显示扩展并设置了P3D软件全屏设置&#xff08;即下面的步骤一&#xff09;保存后…

Flink maven日志配置

Flink maven日志配置 maven 配置 <slf4j.version>1.7.30</slf4j.version> <!-- 引入日志管理相关依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</…

网页设计达人的首选!这6款顶级工具助你设计完美网页!

即时设计 即时设计是国内为当地设计师量身定制的完全免费的网页设计工具。是集成原型、设计、交互、交付等所有网页设计需求的一站式设计平台。内部集成了大量优秀的插件&#xff0c;包括组件、图标、字体、色板、填充等功能&#xff0c;基本涵盖了网页设计师常用的大部分工具…

uniapp写安卓端app自动更新下载apk安装

需要后端返回一个接口&#xff0c;接口里有最新版本号和下载地址&#xff0c;通过对比当前版本号和最新版本号来控制下载和安装最新版本 //获取当前版本 AndroidCheckUpdate() {const systemInfo uni.getSystemInfoSync();this.version Number(systemInfo.appVersion.split(…

Android studio调试

Android Studio连接手机详细教程(包含遇到的问题集)_android studio 连接手机-CSDN博客 可以创建虚拟机或直连真机或直连模拟器。 无法打开本地终端 Android studio Failed to start [powershell.exe] 利用Android studio的adb命令删除app应用 - 简书 利用ADB工具免root停用A…

CSAPP cache lab - Optimizing Matrix Transpose

CSAPP cache lab part B 矩阵转置 矩阵转置是一种操作&#xff0c;它将矩阵的行和列互换位置&#xff0c;即将原始矩阵的行变为转置矩阵的列&#xff0c;将原始矩阵的列变为转置矩阵的行。转置操作可以通过改变矩阵的布局来方便地进行某些计算和分析。 假设有一个mn的矩阵A&…

Java入门高频考查基础知识2(超详细28题2.5万字答案)

Java 是一种广泛使用的面向对象编程语言&#xff0c;在软件开发领域有着重要的地位。Java 提供了丰富的库和强大的特性&#xff0c;适用于多种应用场景&#xff0c;包括企业应用、移动应用、嵌入式系统等。 以下是 Java 基础知识的一个概览&#xff1a; 1. 语法和基本概念&…

速查!优惠券核销情况(支付宝优惠券)

写在前面 在做支付优惠立减引流的时候&#xff0c;经常会遇到明明是符合条件的支付交易&#xff0c;但是不知道为什么就是核销不掉优惠券的情况。 如果是接口接入的情况还好&#xff0c;能通过记录的数据自己排查下原因。 但是如果是支付宝后台配置的一些优惠、立减活动的情…

JDK安装与配置教程来啦

1.从Oracle公司官网下载JDK安装文件。 官网地址为&#xff1a; http://www.oracle.com/technetwork/java/javase/downloads/index.html 目前最新版本是JDK21,下面就以JDK21举例。 2.需要登录Oracle账户&#xff0c;没有的注册一下就行了。 3.在确认安装的盘符&#xff08;例…

java基于ssm框架的少儿编程在线培训系统论文

目 录 目 录 I 1 课题背景及研究内容 4 1.1 课题背景 4 1.2 开发目的和意义 4 2 相关技术和应用 4 2.1 VUE技术 4 2.2 Mysql数据库简介 5 2.3 SSM框架简介 6 2.4 Eclipse简介 6 2.5 B/S系统架构 6 3 系统分析 8 3.1可行性分析 8 3.1.1技术可行性 8 3.1.2经济可行性 8 3.1.3操作…

Redis事务操作

文章目录 1. Redis事务常见命令2. 具体案例 1. Redis事务常见命令 名称描述DISCARD取消事务&#xff0c;放弃执行事务块内的所有命令EXEC执行所有事务块内的命令MULTI表示一个事务块的开始UNWATCH取消WATCH命令对所有keyd监控WATCH eye [key…]监视一个或多个kye&#xff0c;如…

高手总结17个画好原理图的技巧

欧若奇科技 专业电路设计&#xff0c;PCB复制&#xff0c;原理图反推&#xff0c;电子产品优化设计等 不光是代码有可读性的说法&#xff0c;原理图也有。很多时候原理图不仅仅是给自己看的&#xff0c;也会给其它人看&#xff0c;如果可读性差&#xff0c;会带来一系列沟通问…

零基础也可以探索 PyTorch 中的上采样与下采样技术

目录 torch.nn子模块Vision Layers详解 nn.PixelShuffle 用法与用途 使用技巧 注意事项 参数 示例代码 nn.PixelUnshuffle 用法与用途 使用技巧 注意事项 参数 示例代码 nn.Upsample 用法与用途 使用技巧 注意事项 参数 示例代码 nn.UpsamplingNearest2d …

DDNS-GO配置使用教程

环境&#xff1a;openwrt 下载地址&#xff1a;Releases jeessy2/ddns-go GitHub 下载 ssh至openwrt根目录&#xff0c;根据你的处理器选择要下载的版本&#xff0c;我是路由器&#xff0c;选择的是 ddns-go_5.7.1_linux_arm64.tar.gz wget github链接 安装 tar -zxvf…

svn - 配置账号、自动更新、配置log权限

概述 虽然已经有很多朋友的公司都不使用svn了&#xff0c;但也有很多朋友的公司在使用&#xff0c;统一整理了svn的配置账号、自动更新、配置log权限&#xff0c;常用的操作知识。 找到Svn的位置和运行的项目 找到运行中的svn进程PID&#xff0c;/var/svn/,这个就是svn服务启…

计算机网络-2019期末考试解析

【前言】 从内容上看比较像计算机网络课程了&#xff0c;先做了。 一&#xff0e;填空选择题&#xff08;共 20 分&#xff0c;每空 1 分&#xff09; 1 、双绞线由两根相互绝缘的、绞合成均匀的螺纹状的导线组成&#xff0c;下列关于双绞线的叙述&#xff0c;不正确的是___ __…

go语言的http post推送

go语言的网络功能比较强大&#xff0c;使用go语言实现http 协议的推送非常简单&#xff0c;这里做了个简单的post推送示例。 代码 package mainimport ("bytes""fmt""io/ioutil""crypto/tls""net/http""flag" …

[modern c++] std::binder 的返回值用 std::function 保存

前言&#xff1a; 当使用 std::function 保存 std::binder 的返回值时&#xff0c;需要注意所有被 placeholder 占用的参数位置都不应该再出现再 std::function 的模板列表里。 参考&#xff1a; c - std::function and std::bind return value - Stack Overflow Demo&#x…

canvas绘制流动的蚂蚁线(图文示例)

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

sqlilabs第五十一五十二关

Less-51(GET - Error based - ORDER BY CLAUSE-String- Stacked injection) 手工注入 源码 单引号闭合用注释(没有后续输出只能堆叠注入) 自动注入 和上一关一样 Less-52(GET - Bind based - ORDER BY CLAUSE-numeric- Stacked injection) 手工注入 数字类型 不用注释直接…