使用缓存管理器在 Flutter 中下载和缓存文件

简介: 本指南将向您展示如何使用 Flutter 缓存管理器下载和缓存文件。安装包打开您的 pubspec 并添加flutter_cache_manager包。

本指南将向您展示如何使用 Flutter 缓存管理器下载和缓存文件。

安装包

打开您的 pubspec 并添加flutter_cache_manager包。

flutter_cache_manager: ^0.3.2
复制代码

在主文件中,我们将创建一个简单的 UI 来显示一些反馈,以便我们知道发生了什么。我们将有一个材料应用程序并将主页小部件设置为等于我们在下面创建的 HomeView。HomeView 是有状态的,并有一个字符串标题作为成员变量,并在屏幕中央显示该标题。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomeView());
  }
}
class HomeView extends StatefulWidget {
  HomeView({Key key}) : super(key: key);
  _HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
  String title = 'Waiting to download';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
      ),
      body: Center(child: Text(title)),
    );
  }
}
复制代码

我们还有一个带有空 onPressed 的浮动操作按钮。这就是设置。

下载并缓存文件

缓存的工作方式是下载文件并将路径返回给您,它还将该文件缓存在设备的临时文件夹中一段时间。如果您在文件仍然有效时再次请求该文件,则它会立即返回它。如果文件已过期,则再次下载该文件。在按下时,我们将标题设置为“正在下载...”并获取一个文件。文件完成后,我们将在标题中显示文件在磁盘上的路径。

// Add the url
 String url = 'https://firebasestorage.googleapis.com/v0/b/filledstacks.appspot.com/o/filledstacks_tutorials.pdf?alt=media&token=a5e671e7-5acd-4bc4-a167-8d8483954d2a';
 ...
 floatingActionButton: FloatingActionButton(
    onPressed: () async {
      setState(() => title = 'Downloading...');
      var fetchedFile = await DefaultCacheManager().getSingleFile(url);
      setState(() => title = 'File fetched: ${fetchedFile.path}');
    },
  ),
...
复制代码

如果您点击该按钮,那么您将第一次看到“正在下载...”,然后是“文件已获取:文件/路径/”消息。这是多么容易。现在,当您再次点击下载时,您几乎会立即看到获取的文件。这意味着它已被缓存,现在只需通过请求即可轻松访问。

如果您担心每次都创建 DefaultCacheManager 的新实例,则不必担心。它是使用单例模式实现的,因此它只会创建一次对象,并在您构造它时将该实例返回给您。

// Package code
static DefaultCacheManager _instance;
 factory DefaultCacheManager() {
    if (_instance == null) {
      _instance = new DefaultCacheManager._();
    }
    return _instance;
  }
复制代码

所以无需担心。继续使用DefaultCacheManager().

自定义缓存管理器

您可能需要一些不同的缓存设置。您可能希望限制您的应用程序可以缓存的对象数量以节省用户空间,您可能希望设置更短的缓存持续时间(默认 30 天),甚至提供您自己的文件处理程序。让我们来看看如何做到这一点。

该包为您提供BaseCacheManager了可以在您自己的代码中扩展和实现的功能。创建一个扩展 BaseCacheManager 的新类 CustomCacheManager。有一种必需的方法getFilePath可以返回将用于缓存的文件夹的基本路径。您还必须为超类提供一个缓存键来标识您的缓存。通过这种方式,您可以让不同的缓存指向不同的文件夹并且具有唯一的键。我们将我们的密钥存储为 const 并将其提供给 super。

...
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
class CustomCacheManager extends BaseCacheManager {
  static const key = "pdfCache";
  CustomCacheManager() : super(key);
  @override
  Future<String> getFilePath() {
    return null;
  }
}
复制代码

对于该getFilePath函数,我们将返回我们正在运行的设备的临时目录的路径,并将我们的密钥附加到末尾,以便我们可以根据需要识别磁盘上的缓存。

...
@override
Future<String> getFilePath() async {
  var directory = await getTemporaryDirectory();
  return path.join(directory.path, key);
}
...
复制代码

这就是自定义缓存所需的全部内容,现在我们可以添加一些其他设置。假设我们只希望最多缓存 10 个文件,并且每个文件只应缓存 30 秒。这是我们如何实现这一目标。

...
// Add const values at the top
static const int maxNumberOfFiles = 10;
static const Duration cacheTimeout = Duration(seconds: 30);
// pass values into super
CustomCacheManager()
    : super(
        key,
        maxNrOfCacheObjects: maxNumberOfFiles,
        maxAgeCacheObject: cacheTimeout
      );
...
复制代码

我们可以用我们的 CustomCacheManager 交换 DefaultCacheManager。我们将在 build 方法之外创建一个实例,因此它只创建一次。

// Create instance 
CustomCacheManager cacheManager = CustomCacheManager();
... 
// use in the floating action button on pressed
floatingActionButton: FloatingActionButton(
  onPressed: () async {
    setState(() => title = 'Downloading...');
    var fetchedFile = await cacheManager.getSingleFile(url);
    setState(() => title = 'File fetched: ${fetchedFile.path}');
  },
),
...
复制代码

点击 FAB 仍然会给你相同的结果,但现在你会看到你的缓存的键也在路径中。这表明它现在正在通过您的缓存。如果您等待 30 秒并点击,您会看到它再次需要很长时间,这是因为文件已过期。十分简单。

您还可以通过为返回 FileFetcherResponse 对象的 fileFetcher 属性提供 Future 来实现您自己的文件提取器。

CustomCacheManager()
  : super(
      key,
      maxNrOfCacheObjects: maxNumberOfFiles,
      maxAgeCacheObject: cacheTimeout,
      fileFetcher: _customHttpGetter
    );
static Future<FileFetcherResponse> _customHttpGetter(String url, {Map<String, String> headers}) async {
  // Do things with headers, the url or whatever.
  return HttpFileFetcherResponse(...);
}
复制代码

这里的所有都是它的。您现在应该能够有效地处理 Flutter 应用程序中的缓存。我建议使用 DefaultCacheManager 实现与上面显示的相同的单例模式。这样您就不会两次构造相同的缓存。



相关文章
|
6月前
|
存储 缓存 Android开发
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【远程url】音频,搭配Okhttp库进行下载和缓存,播放完随机播放下一首
这是一个Kotlin项目,使用Jetpack Compose和ExoPlayer框架开发Android应用,功能是播放远程URL音频列表。应用会检查本地缓存,如果文件存在且大小与远程文件一致则使用缓存,否则下载文件并播放。播放完成后或遇到异常,会随机播放下一首音频,并在播放前随机设置播放速度(0.9到1.2倍速)。代码包括ViewModel,负责音频管理和播放逻辑,以及UI层,包含播放和停止按钮。
|
7月前
|
XML 存储 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache管理器的实战开发指南(修正篇)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache管理器的实战开发指南(修正篇)
116 0
|
1月前
flutter 用PUT的方式传输文件不带分隔符
flutter 用PUT的方式传输文件不带分隔符
14 4
|
2月前
|
SQL 缓存 Java
JVM知识体系学习三:class文件初始化过程、硬件层数据一致性(硬件层)、缓存行、指令乱序执行问题、如何保证不乱序(volatile等)
这篇文章详细介绍了JVM中类文件的初始化过程、硬件层面的数据一致性问题、缓存行和伪共享、指令乱序执行问题,以及如何通过`volatile`关键字和`synchronized`关键字来保证数据的有序性和可见性。
31 3
|
2月前
|
缓存 开发框架 移动开发
uni-app:下载使用uni&创建项目&和小程序链接&数据缓存&小程序打包 (一)
uni-app 是一个跨平台的开发框架,它允许开发者使用 Vue.js 来构建应用程序,并能够同时发布到多个平台,如微信小程序、支付宝小程序、H5、App(通过DCloud的打包服务)等。uni-app 的目标是通过统一的代码库,简化多平台开发过程,提高开发效率。 在这一部分中,我们将逐步介绍如何下载和使用uni-app、创建一个新的项目、如何将项目链接到小程序,以及实现数据缓存的基本方法。
|
4月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
131 1
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
4月前
|
存储 缓存 NoSQL
【Azure Redis 缓存 Azure Cache For Redis】如何设置让Azure Redis中的RDB文件暂留更久(如7天)
【Azure Redis 缓存 Azure Cache For Redis】如何设置让Azure Redis中的RDB文件暂留更久(如7天)
|
4月前
|
缓存 NoSQL Redis
【Azure Redis 缓存】Azure Cache for Redis 服务的导出RDB文件无法在自建的Redis服务中导入
【Azure Redis 缓存】Azure Cache for Redis 服务的导出RDB文件无法在自建的Redis服务中导入
|
4月前
|
缓存 NoSQL 算法
【Azure Redis 缓存】Redis导出数据文件变小 / 在新的Redis复原后数据大小压缩近一倍问题分析
【Azure Redis 缓存】Redis导出数据文件变小 / 在新的Redis复原后数据大小压缩近一倍问题分析
|
4月前
|
SQL 缓存 监控
实时计算 Flink版产品使用问题之怎么手动清理缓存或废弃文件
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。