【Android】线程下载资源保证资源到位采用了 OkHttp的三方网络下载 文件缓存策略

news2025/1/14 5:08:41

背景

使用 SVGA的三方的url播放方式会比较慢,至少延迟3s以上才会出现svga效果,所以改变策略:将线上的svga全部下载到本地进行播放,那么就得将采用网络缓存的方式实现效果。
在这里插入图片描述

实现

那么就得实现以下几点:

  • 初次下载
  • 缓存
  • 判重下载

下载的地址就放在这里。这里也是常规的文件路径下载

在这里插入图片描述

通过上下文类获取即可,如果参数路径没有,就会再构建一个新的路径下载。
整理的代码如下:

  // 获取当前的animation 文件夹
        String cacheDir = context.getExternalFilesDir(getAnimFilesName()).getAbsolutePath();

        // 挂个线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 循环当前的礼物svag 获取
                for (GiftInfo giftInfo : giftInfoList) {
                    /**
                     * 名称规则
                     * 纯 id 加 文件后缀
                     */
                    String name = giftInfo.getId() + ".svga";
                    File svgaFile = new File(cacheDir, name);
                    // 判断去重
                    if (svgaFile.exists()) {
                        Log.i(TAG, "svgaFile.exists" + svgaFile.getAbsolutePath());
                        continue;
                    }

                    // 网络下载
                    Request request = new Request.Builder()
                            .url(giftInfo.getSvga())
                            .build();

                    APIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(@NonNull Call call, @NonNull IOException e) {
                            Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());
                            // 下载失败的处理
                            giftInfoList.remove(giftInfo);
                        }

                        @Override
                        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                            if (response.isSuccessful()) {
                                // 将 SVGA 文件保存到缓存目录中
                                FileOutputStream outputStream = new FileOutputStream(svgaFile);
                                outputStream.write(response.body().bytes());
                                outputStream.close();
                                Log.i(TAG, "svgaFile donwload onResponse" + response.message());
                                // 下载成功后,处理逻辑
                            } else {
                                // 下载失败的处理
                                pLog.e(TAG, "svgaFile donwload onResponse" + response.message());
                                giftInfoList.remove(giftInfo);
                            }
                        }
                    });
                }
            }
        }).start();
  • 文件存储路径
String cacheDir = context.getExternalFilesDir(getAnimFilesName()).getAbsolutePath();
String name = giftInfo.getId() + ".svga";
File svgaFile = new File(cacheDir, name);
  • 判重下载
// 在for 循环下:
					 /**
                     * 名称规则
                     * 纯 id 加 文件后缀
                     */
                    String name = giftInfo.getId() + ".svga";
                    File svgaFile = new File(cacheDir, name);
                    // 判断去重
                    if (svgaFile.exists()) {
                        Log.i(TAG, "svgaFile.exists" + svgaFile.getAbsolutePath());
                        continue;
                    }
  • 网络下载

走okhttp的三方,并通过字节码转化为对应的文件

 APIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(@NonNull Call call, @NonNull IOException e) {
                            Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());
                            // 下载失败的处理
                            giftInfoList.remove(giftInfo);
                        }

                        @Override
                        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                            if (response.isSuccessful()) {
                                // 将 SVGA 文件保存到缓存目录中
                                FileOutputStream outputStream = new FileOutputStream(svgaFile);
                                outputStream.write(response.body().bytes());
                                outputStream.close();
                                Log.i(TAG, "svgaFile donwload onResponse" + response.message());
                                // 下载成功后,处理逻辑
                            } else {
                                // 下载失败的处理
                                pLog.e(TAG, "svgaFile donwload onResponse" + response.message());
                                giftInfoList.remove(giftInfo);
                            }
                        }
                    });
                }
            }
        }).start();

待优化 线程使用

毕竟这个是挂线程的方式,没有在项目中用到更加稳定的线程处理方式。这是整个的一个遗憾。
所以下面我提供一个思路:可以阅读一下雪峰大佬的文字:
线程池的使用

  // 挂个线池
        ExecutorService service = Executors.newFixedThreadPool(10);
        // 循环当前的礼物svag 获取
        for (GiftInfo giftInfo : giftInfoList) {
            /**
             * 名称规则
             * 纯 id 加 文件后缀
             */
            String name = giftInfo.getId() + ".svga";
            File svgaFile = new File(cacheDir, name);
            if (svgaFile.exists()) {
                Log.i(TAG, "svgaFile.exists" + svgaFile.getAbsolutePath());
                continue;
            }
            service.execute(new Runnable() {
                @Override
                public void run() {
                    // 网络下载
                    Request request = new Request.Builder()
                            .url(giftInfo.getSvga())
                            .build();

                    WendyAPIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(@NonNull Call call, @NonNull IOException e) {
                            Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());
                            // 下载失败的处理
                            giftInfoList.remove(giftInfo);
                        }

                        @Override
                        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                            if (response.isSuccessful()) {
                                // 将 SVGA 文件保存到缓存目录中
                                FileOutputStream outputStream = new FileOutputStream(svgaFile);
                                outputStream.write(response.body().bytes());
                                outputStream.close();
                                Log.i(TAG, "svgaFile donwload onResponse" + response.message());
                                // 下载成功后,处理逻辑
                            } else {
                                // 下载失败的处理
                                Log.e(TAG, "svgaFile donwload onResponse" + response.message());
                                giftInfoList.remove(giftInfo);
                            }
                        }
                    });
                }
            });

        }
        // 记得关闭
        service.shutdown();

效果如下:
还行~
在这里插入图片描述

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

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

相关文章

文件内容显示

一.浏览普通文件 .1. 文件内容查看 1.1.1. cat 命令 作用:查看文件内容,适合数据量较少 格式:cat -参数 文件名 参数: -n:显示行号,加上 -b:文件中所有非空行增加行号,编号从1开始…

Leetcode | 304. 二维区域和检索 - 矩阵不可变

304. 二维区域和检索 - 矩阵不可变 文章目录 [304. 二维区域和检索 - 矩阵不可变](https://leetcode.cn/problems/range-sum-query-2d-immutable/)题目官方题解:二维前缀和 题目 给定一个二维矩阵 matrix,以下类型的多个请求: 计算其子矩形…

DA3 网站的第10位用户信息读取

目录 1.题目描述 2.输入描述 3.输出描述 4.题目分析 5.通过代码 1.题目描述 现有一个Nowcoder.csv文件,它记录了牛客网的部分用户数据,包含如下字段(字段与字段之间以逗号间隔): Nowcoder_ID:用户ID …

绘图系统五:数据产生

文章目录 AxisFrame组件源码模式序列化导入数据获取文件信息导入文本导入二进制数据 📈一 三维绘图系统 📈二 多图绘制系统📈三 坐 标 轴 定 制 📈四 定制绘图风格源码地址 Python打造动态绘图系统 AxisFrame组件 AxisFrame是存…

热电偶的工作原理

当有两种不同的导体或半导体A和B组成一个回路,其两端相互连接时,只要两结点处的温度不同,一端温度为T,称为工作端或热端,另一端温度为T0 ,称为自由端(也称参考端)或冷端,…

使用递归思想遍历二叉树

二叉树的遍历主要有两种方式:深度优先遍历和广度优先遍历 这篇主要讲使用深度优先遍历来遍历二叉树 深度优先遍历有以下三种 前、中、后序遍历,这三种遍历方式的主要区别是中间节点的位置所在的顺序 前序遍历:中间节点在叶子节点前面 中序遍历…

EPLAN_001#常用功能(一)

一、栅格设置、背景颜色设置 二、插入设备图标(快捷键 Insert) 按TAB旋转方向 三、 通过左CTRLENTER输入 四、移动属性文本、复制格式 CTRLB 可以移动设备图形中的相关文本(或者右键—文本—移动属性文本) 很对多个文本的&#xf…

ElasticSearch进阶:一文全览各种ES查询在Java中的实现

ElasticSearch进阶:一文全览各种ES查询在Java中的实现 ElasticSearch进阶:一文全览各种ES查询在Java中的实现 es基本语句详解 查询语句详解 前言 ElasticSearch第一篇:ElasticSearch基础:从倒排索引说起,快速认知ES …

Setup exvim enviroment

1. 官方网站 exvim官方网站 sudo apt-get install ctags id-utils cscope silversearcher-ag 2. vundle管理plugins 【NOTE】按照官网安装步骤,会安装一些默认plugins。 查看和修改.vimrc.plugins 打开默认未安装的plugins,比如airline. 打开plugi…

2023华为杯研究生数学建模竞赛E题思路分析+代码+论文

如下为C君撰写的2023华为杯研究生数学建模竞赛E题思路分析,代码论文见文末。 E题思路 出血性脑卒中临床智能诊疗建模 一、 背景介绍 出血性脑卒中指非外伤性脑实质内血管破裂引起的脑出血,占全部脑卒中发病率的10-15%。其病因复杂,通常因脑…

Vue构建SPA项目实现路由

目录 前言 一、Vue CLI简介 1.什么是Vue CLI 2.Vue CLI的特点 二、SPA项目搭建 1.安装Vue CLI 2.使用脚手架vue-cli来构建项目 ​编辑 3.项目结构说明 4.什么是*.vue文件 三、基于SPA完成路由并嵌套路由 1.基于SPA完成路由 1. 1在src下的components 创建自定义组件…

动态代理原理和设计模式详解

一、什么是代理模式代理模式是一种设计模式,提供了对目标对象额外的访问方式,即可以通过代理访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的方式进行访问,扩展目标对象的功能。 通俗的说,例…

html学习综合案例1

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>个人简介</title> </head> <body>…

【从0学习Solidity】9. 常数 constant和immutable

【从0学习Solidity】9. 常数 constant和immutable 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&…

golang入门笔记——pprof性能分析

文章目录 简介runtime/pprof的使用命令行交互网络服务性能分析pprof与性能测试结合压测工具go-wrk 简介 golang性能分析工具pprof的8个指标 1.性能分析的5个方面&#xff1a;CPU、内存、I/O、goroutine&#xff08;协程使用情况和泄漏检查&#xff09;、死锁检测以及数据竟态…

JavaBean文字格斗游戏之进阶版

以上都是关于role类的定义 求赞!

go 内存泄露

事件回顾 9.15号晚18点服务端发版9.16号晚21点监控显示自发版后服务器 TCP_alloc 指标一路飙升至40K(如图) 问题分析 看到 tcp_alloc 指标异常&#xff0c;初步怀疑有tcp连接创建后未关闭&#xff0c;应该是上次发版写了什么代码导致的。回顾此次发版清单&#xff0c;问题应该…

IBM LSF 任务调度系统的主要术语和概念

LSF 术语和概念 了解 IBM LSF 基本术语和概念。 作业状态 IBM Spectrum LSF 作业具有多个状态。 PEND 正在队列中等待调度和分派。 RUN 已分派到主机并正在运行。 DONE 正常完成&#xff0c;退出值为零。 EXIT 已完成&#xff0c;具有非零退出值。 PSUSP 作业处于暂…

FBX文件结构解读【文本格式】

FBX 格式几乎受到所有 3D 引擎的支持&#xff0c;是 Autodesk 开发的 3D 模型的专有格式。它支持顶点、索引、法线、UV坐标、材质和动画。 FBX还支持许多其他类型的信息&#xff0c;但它们对游戏引擎几乎没有用处。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 有两种…

【C++】String类基本接口介绍及模拟实现(多看英文文档)

string目录 如果你很赶时间&#xff0c;那么就直接看我本标题下的内容即可&#xff01;&#xff01; 一、STL简介 1.1什么是STL 1.2STL版本 1.3STL六大组件 1.4STL重要性 1.5如何学习STL 二、什么是string&#xff1f;&#xff1f;&#xff08;本质上是一个类&#xff0…