使用缓存管理器在 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 实现与上面显示的相同的单例模式。这样您就不会两次构造相同的缓存。



相关文章
|
7天前
|
缓存 数据处理 Python
python读取文件到缓存
python读取文件到缓存
12 1
|
1月前
|
缓存 Linux 应用服务中间件
linux yum下载离线包缓存 安装到服务器 实测!!!
linux yum下载离线包缓存 安装到服务器 实测!!!
29 0
|
5月前
|
存储 缓存
Flutter 文件读写---path_provider
Flutter 文件读写—path_provider 在Flutter中,可以通过path_provider库来实现文件的读写操作。这个库提供了许多方法,可以方便地获取设备上的常用目录,比如文档目录、下载目录、临时目录等。
|
9月前
|
存储 缓存 自然语言处理
webpack + express 实现文件精确缓存
webpack + express 实现文件精确缓存
49 0
|
10月前
|
存储 缓存 iOS开发
iOS 轻量化动态图像下载缓存框架实现
日常开发过程中,图片的下载会占用大量的带宽,图片的加载会消耗大量的性能和内存,正确的使用图片显得尤为重要。 同样也经常需要在各类型控件上读取网络图片和处理本地图片,例如:UIImageView、UIBtton、NSImageView、NSButton等等。
iOS 轻量化动态图像下载缓存框架实现
|
11月前
|
开发框架 Dart 测试技术
Flutter 应用开发的pubspec.yaml文件说明
Flutter 应用开发的pubspec.yaml文件说明
|
11月前
|
Dart 开发工具 Android开发
flutter 的 pubspec.yaml 文件解析
pubspec.yaml 文件是 Flutter 项目的核心配置文件,用于定义项目的元数据、依赖关系、资源文件和环境约束等等。本文对该文件中的所有配置依据类别进行一一讲解,并给出相应的示例。
221 0
|
11月前
|
SQL 缓存 分布式计算
SPARK中InMemoryFileIndex文件缓存导致的REFRESH TABLE tableName问题
SPARK中InMemoryFileIndex文件缓存导致的REFRESH TABLE tableName问题
169 0
flutter系列之:做一个下载按钮的动画
我们在app的开发过程中经常会用到一些表示进度类的动画效果,比如一个下载按钮,我们希望按钮能够动态显示下载的进度,这样可以给用户一些直观的印象,那么在flutter中一个下载按钮的动画应该如何制作呢? 一起来看看吧。
|
12月前
|
缓存 Java Spring
Spring Cache抽象-缓存管理器
Spring Cache抽象-缓存管理器
78 0