使用OkHttp 缓存 API 调用提高Android应用性能

使用OkHttp 缓存 API 调用提高Android应用性能

坦率地说,我们都遇到过这样的情况——焦急地刷新应用,看着加载图标不停地旋转,等待那个至关重要的 API 响应。这样的等待我们已经是炉火纯青了,是吧?手指有节奏地轻敲屏幕,微微转动着眼珠,嘴里不那么轻声地嘀咕着:“拜托,赶紧给我数据!”构建与外部 API 交互的应用时,缓存可谓是一项利器。API 调用往往速度缓慢、资源占用大,还受到 API 提供者的速率限制。但是,通过实施强大的缓存机制,你可以极大地减少 API 调用的次数、降低响应时间,并提供更加流畅的用户体验。解决重复 API 调用问题的方法之一就是在本地缓存/存储它们的响应。本文将介绍如何利用 OkHttp 库的 CacheControl 类来存储具有时间有效性的 API 响应。

实施缓存

定义缓存大小和实例

要能够将 API 调用的响应本地存储到缓存中,首先,我们需要定义缓存并通知客户端。在下面的代码片段中,我们使用 okhttp 库中的 Cache 类定义了缓存。我们将此缓存的最大大小设置为 5 MB。然后,在初始化 okhttpclient 参数时使用 cache() 函数。

//OkHttpClient.kt
// Defining a cache of 5 MB size
val cacheSize = (5 * 1024 * 1024).toLong()//Initializing instance of Cache class
val myCache = Cache(context.cacheDir, cacheSize)//defining okhttpclient instance
val okHttpClient = OkHttpClient.Builder().cache(myCache).build()

定义缓存规则

根据设备是否连接到互联网,让我们来定义一些基本的网络缓存规则:

  • 如果设备连接到互联网:如果最后一次 API 响应是在不到 30 分钟之前检索的,则显示缓存的响应;否则,获取新的响应并将其存储在缓存中。
  • 如果设备离线:使用最多 1 天前的 API 响应以保持应用程序功能。

你可以为你的项目定义不同且更为细致的规则来应对复杂的情况,但为了简单起见,我们将采用上述规则。

第一步是检查用户是否连接到互联网。为此,我们可以使用 ConnectivityManager 类收集数据并检查用户是否连接到互联网。让我们来定义一个名为 hasNetwork() 的函数,如下所示:

//CheckNetwork.kt
fun hasNetwork(context: Context): Boolean {val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerval nw      = connectivityManager.activeNetwork ?: return falseval actNw = connectivityManager.getNetworkCapabilities(nw) ?: return falsereturn when {actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> trueactNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> trueactNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> trueactNw.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> trueelse -> false}
}

我们检查用户是否连接到WiFi、蜂窝移动网络或蓝牙网络,并根据情况返回true或false。

为了实现我们缓存规则的定义,我们将使用 OkHttp 库中的一个组件,叫做 Interceptor。拦截器是一个强大的机制,允许您在应用程序发送或接收 HTTP 请求和响应之前拦截、处理甚至修改它们。它们在通信流程中起到中间人的作用,让您更加灵活地控制 OkHttp 处理网络请求的方式。

在拦截器中,我们将提供指导,告诉我们的 okHttpClient 实例何时使用缓存响应。

在构建客户端实例时,让我们使用 addInterceptor() 函数来添加拦截器。我们可以在这个函数中修改我们的 API 请求。在 lambda 函数中,我们可以获取请求对象,并在最终发送到服务器之前对其进行修改。为了添加缓存功能,我们使用 cacheControl() 函数,该函数接受 CacheControl 类的参数。

我们需要实现的第一条规则是,如果设备连接到互联网,则使用 30 分钟前的响应(如果有的话),否则获取新的响应。我们使用 maxAge() 函数来实现这一点。

我们需要实现的第二条规则是,如果设备断开连接,则使用最多 1 天前的响应。为此,我们使用 maxStale() 函数。

// Defining a cache of 5 MB size
val cacheSize = (5 * 1024 * 1024).toLong()//Initializing instance of Cache class
val myCache = Cache(context.cacheDir, cacheSize)//defining okhttpclient instance
val okHttpClient = OkHttpClient.Builder().cache(myCache).addInterceptor { chain ->var request = chain.request()request = if (hasNetwork(context))request.newBuilder().cacheControl(CacheControl.Builder().maxAge(30, TimeUnit.MINUTES).build()).build()elserequest.newBuilder().cacheControl(CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build()).build()chain.proceed(request)}.build()

maxAge() 与 maxStale() 的区别

max-agemax-stale 是 HTTP 缓存中用来控制响应新鲜度的指令。它们有着不同的含义:

  • max-age:指定客户端认为缓存响应是新鲜的最大时间,以秒为单位。如果响应的年龄超过了 max-age,客户端将认为该响应已过期,并尝试从服务器获取新的响应。

  • max-stale:告知客户端即使响应已过期,仍可接受,但仅在指定的最大过期时间内。同样以秒为单位。

以上是它们的区别。现在我们已经在 OkHttpClient 中实现了缓存系统,是时候为你的项目构建一个快速可靠的用户体验了。如果你使用 Retrofit 作为 OkHttp 的封装器,也可参考以下代码片段来实现缓存!

//RetrofitClient.kt 
class RetrofitClient(private val context: Context) {val cacheSize = (5 * 1024 * 1024).toLong()val instance: Api by lazy {val myCache = Cache(context.cacheDir, cacheSize)val okHttpClient = OkHttpClient.Builder().cache(myCache).addInterceptor { chain ->var request = chain.request()request = if (hasNetwork(context))request.newBuilder().cacheControl(CacheControl.Builder().maxAge(30, TimeUnit.MINUTES).build()).build()elserequest.newBuilder().cacheControl(CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build()).build()chain.proceed(request)}.addInterceptor(HttpLoggingInterceptor().apply {this.level = HttpLoggingInterceptor.Level.BODY }).build()val retrofit = Retrofit.Builder().baseUrl("BASE_URL").addConverterFactory(GsonConverterFactory.create()).client(okHttpClient).build()retrofit.create(Api::class.java)}
}

现在,你可以开始在实际设备或模拟器上运行你的项目了。要检查缓存是否有效,请使用Android Studio中的App Inspection标签页,或者使用OkHttp的日志拦截器来记录所有网络调用。

结论

对于长时间不变的API响应,可以通过上述技术进行缓存,从而节省大量资源。软件开发始终涉及根据时间和空间做出一定的权衡。在这种情况下,我们为了节省时间而牺牲了一点空间(用于存储API响应)。

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

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

相关文章

《R语言与农业数据统计分析及建模》——多重共线性和逐步回归

一、多重共线性 多重共线性:在多元线性回归时,多个自变量之间存在高度相关关系,时模型估计失真或难以估计准确的情况。 一般地,多元线性回归中自变量间应尽量相互独立。常规模型诊断方法难以检测多重共线性。 1、案例解释 作物产…

ActiveMQ 反序列化漏洞 (CVE-2015-5254)

一、漏洞描述 Apache ActiveMQ 是由美国阿帕奇(Apache)软件基金会开发的开源消息中间件,支持 Java 消息服务、集群、Spring 框架等。属于消息队列组件(消息队列组件:分布式系统中的重要组件,主要解决应用耦合、异步消息…

数据库|TiDB-Server API的高效应用指南

一、API介绍 1.Status 显示TiDB 连接数、版本和git_hash 信息 tidb-server_ip:status_port/status { "connections": 0, "version": "5.7.25-TiDB-v6.1.1", "git_hash": "5263a0abda61f102122735049fd0dfadc7b7f822" } 2.St…

mysql-sql-练习题-4-标记

标记 连续登录2-7天用户建表排名找规律 最大连胜次数建表只输出连胜结果输出所有连续结果 连续登录2-7天用户 建表 create table continuous_login(user_id1 integer comment 用户id,date_login date comment 登陆日期 ) comment 用户登录表;insert into continuous_login val…

LT2611UX四端口 LVDS转 HDMI2.0,带音频

描述LT2611UX 是一款面向机顶盒、DVD 应用的高性能 LVDS 至 HDMI2.0 转换器。LVDS输入可配置为单端口、双端口或四端口,具有1个高速时钟通道和3~4个高速数据通道,工作速率最高为1.2Gbps/通道,可支持高达19.2Gbps的总带宽。LT2611UX 支持灵活的…

002 springCloudAlibaba Sentinel流控-关联

当与A关联的资源B达到阀值后,就限流A自己 文章目录 FlowLimitController.javaSentinelServerApplication.javaServletInitializer.javaapplication.yamlpom.xmlpom.xml 启动Sentinel8080 - java -jar sentinel-dashboard-1.7.0.jar 启动微服务8401 启动8401微服务…

72、栈-每日温度

思路&#xff1a; 第一种方法&#xff0c;双循环&#xff0c;第一层循环拿出一个元素&#xff0c;第二层循环寻找最近比当前大的元素位置。 第二种方法&#xff1a;使用栈来实现。 初始化&#xff1a; int[] ans 用来存储每一天之后多少天温度会升高。Stack<Integer> 用…

Java | AI+编程 | 如何使用通义灵码提升开发效率

大家好&#xff0c;我是程序员影子 | 全网同名 一名致力于帮助更多朋友快速入门编程的程序猿 今天&#xff0c;我将以小白入门的视角带着大家学会如何在Idea上使用通义灵码&#xff0c;提高开发效率&#xff0c;减少重复工作&#xff1b;话不多说&#xff0c;我们直接进入正题…

golang beego结合wire依赖注入及自动路由

1 安装wire 1.1 通过命令直接安装 go install github.com/google/wire/cmd/wirelatest 1.2 通过go get方式安装 go get github.com/google/wire/cmd/wire进入目录编译 cd C:\Users\leell\go\pkg\mod\github.com\google\wirev0.6.0\cmd\wire go build 然后将wire.exe移动到…

广交会烹饪机器人用上大模型 支付宝小程序云提供技术支持

近日&#xff0c;第135届广交会正在火热进行&#xff0c;记者获悉&#xff0c;支付宝小程序云助力合作伙伴田螺云厨&#xff0c;在烹饪机器人上开始用上大模型技术。各类智能产品的亮相&#xff0c;从中国制造迈向中国创造&#xff0c;也成为广交会的一个亮点。 &#xff08;图…

鲲鹏华为云--OBS

文章目录 1.创建桶2.上传对象3.下载对象4.分享对象5. 删除对象6.删除桶 1.创建桶 创建桶 2.上传对象 点击创建的桶–“上传对象” 拖拽本地文件或文件夹至“上传对象”区域框内添加待上传的文件。 也可以通过单击“上传对象”区域框内的“添加文件”&#xff0c;选择本地…

C语言函数指针的使用、函数指针数组及使用、指向函数指针数组的指针,指针进阶版的冒泡排序等介绍

文章目录 前言一、函数指针的使用1. 加减乘除计算器普通实现2. 加减乘除计算机函数指针实现 二、函数指针数组1. 函数指针数组的书写2. 两个有趣的代码3. 函数指针数组的使用 三、指向函数指针数组的指针四、指针进阶_冒泡排序1.整型冒泡排序2. C语言qsort函数3. 仿写C语言qsor…

ChatGLM2-6B的部署步骤_A3

ChatGLM2-6B 下载地址 一、VisualGLM-6B环境安装 1、硬件配置 操作系统&#xff1a;Ubuntu_64&#xff08;ubuntu22.04.3&#xff09; GPU&#xff1a;4050 显存&#xff1a;16G 2、配置环境 建议最好自己新建一个conda环境 conda create -n chatglm2 python3.8pip …

【Java】HOT100 贪心算法

目录 理论基础 一、简单贪心 LeetCode455&#xff1a;分发饼干 二、中等贪心 2.1 序列问题 LeetCode376&#xff1a;摆动序列 2.2 贪心股票问题 LeetCode121&#xff1a;买卖股票的最佳时机 LeetCode121&#xff1a;买卖股票的最佳时机ii 2.3 两个维度权衡问题 LeetCode135&…

UE Snap03 启动参数设置

UE Snap03 启动参数设置 UE打包后传入自定义参数及解析。 void UGameInstance::StartGameInstance() {Super::StartGameInstance();UE_LOG(LogTemp, Warning, TEXT("--StartGameInstance--"));FString param;FParse::Value(FCommandLine::Get(), TEXT("-UserN…

美团商城代付系统源码

超火的美团代付微信小程序是一种便捷的线上支付工具&#xff0c;让用户可以方便地在微信小程序中完成美团订单的支下面是将美团代付微信小程序源码搭建的相关步骤&#xff1a; 测试网站,页面放后面&#xff0c;可以定制哦 我收了几百块就帮我另外一个客户搭建好了 搭建教程: 以…

前端VUE项目中使用async()用法是为什么?能不用吗?

使用 async 关键字来定义一个函数主要有几个原因&#xff1a; 支持 await 关键字&#xff1a; async 函数允许你在其中使用 await 关键字&#xff0c;这使得你可以在不阻塞程序执行的情况下&#xff0c;等待一个异步操作&#xff08;如网络请求、文件读写等&#xff09;的完成。…

Nutch库入门指南:利用Java编写采集程序,快速抓取北京车展重点车型

概述 在2024年北京车展上&#xff0c;电动汽车成为全球关注的焦点之一。这一事件不仅吸引了全球汽车制造商的目光&#xff0c;也突显了中国市场在电动汽车领域的领先地位。117台全球首发车的亮相&#xff0c;其中包括30台跨国公司的全球首发车和41台概念车&#xff0c;彰显了中…

长难句打卡4.29

If appropriate public policies were in place to help all women—whether CEOs or their children’s caregivers—and all families, Sandberg would be no more newsworthy than any other highly capable person living in a more just society 如果能制定适当的公共政策…

张鸣独到政治观,规矩与自信新解

张鸣独解规矩与自信&#xff0c;社政新影响揭秘。张鸣独到政治观&#xff0c;规矩与自信新解在当今社会政治的大背景下&#xff0c;学者张鸣的每一次公开演讲无疑都是一次思想的盛宴。最近&#xff0c;他就当前的社会政治问题提出了自己独特的观点&#xff0c;特别是他对规矩和…