Flutter缓存管理插件cache_systems的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter缓存管理插件cache_systems的使用

本包用于在设备上缓存文件。它可以用于缓存图像、视频、音频、文本和其他文件。它还可以用于从互联网缓存文件。

初始化配置

在项目的pubspec.yaml文件中添加cache_systems插件:

dependencies:
  flutter:
    sdk: flutter
  cache_systems: ^[version] # 确保始终使用最新版本

添加依赖后,运行以下命令以获取该包:

flutter pub get

使用

从互联网缓存文件

首先,在main()函数中调用CacheSystem().init()来初始化缓存系统。这将使用默认值初始化缓存系统。你也可以通过init()函数传递stalePeriod参数来设置缓存系统的过期时间。过期时间是在缓存被视为过期并被删除的时间。默认情况下,过期时间为7天。

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await CacheSystem().init(stalePeriod: const Duration(days: 7));
  runApp(const MyApp());
}

要从互联网缓存文件,使用CacheSystem().get()函数。此函数接受要缓存的文件的URL作为参数。URL类型必须为Uri。它返回一个包含CacheFile对象的Future

class CacheFile {
  @HiveField(0)
  String path;
  @HiveField(1)
  DateTime? expiration;
  @HiveField(2)
  String fileType;
  
  CacheFile(this.path, this.fileType, {this.expiration});

  File get file => File(path);
}

CacheFile对象包含缓存文件的路径、文件的过期日期和文件类型。CacheFile对象的file属性返回缓存文件的File对象。

final String url = Uri.parse('https://fastly.picsum.photos/id/91/1500/1500.jpg?hmac=gFLcWG7TwMqsOm5ZizQJNJ2tYsENkSQdMMmNNp8Avvs');
final CacheFile? cachedfile = await CacheSystem().get(url);

if (cachedfile != null) {
  print(cachedfile.file.path);
}

如果文件是图像并且你想在UI中渲染它,可以使用FutureBuilder小部件来渲染图像。

FutureBuilder<CacheFile?>(
  future: CacheSystem().get(
    imgUri,
    fileType: CacheFileType.image,
  ),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return Padding(
        padding: const EdgeInsets.all(8.0),
        child: Image.file(
          snapshot.data!.file,
          height: 100,
          width: 100,
        ),
      );
    }
    return const SizedBox.shrink();
  },
);

或者,你可以使用CachedImage小部件来渲染图像。CachedImage小部件接受图像的URL作为参数,并返回一个Image小部件。

CachedImage(url: imgUri)

如果你想获取所有缓存的文件,可以使用CacheSystem().getAllFiles()函数。此函数返回一个包含CacheFile对象列表的Future

final List<CacheFile?> files = await CacheSystem().getAllFiles();
for (final file in files) {
  print(file!.file.path);
}

Web支持(Service Worker)

要在Web上使用缓存系统,你需要向你的Web项目添加一个Service Worker。可以通过在项目中创建一个web文件夹并在web文件夹中添加一个service_worker.js文件来添加Service Worker。service_worker.js文件应包含以下代码:

const BASE_URL = "https://fastly.picsum.photos"; // 你要缓存的文件的URL

const cacheName = "file-cache-v3.1"; // 更改缓存名称以更新缓存

self.addEventListener("install", (event) => {
  self.skipWaiting();
  event.waitUntil(caches.open(cacheName));
});

self.addEventListener("activate", (event) => {
  console.log("Activating Cache service worker");
});

self.addEventListener("fetch", (event) => {
  if (event.request.url.includes(BASE_URL)) {
    event.respondWith(
      caches
        .match(event.request)
        .then((response) => {
          if (response) {
            return response;
          }

          return fetch(event.request).then((response) => {
            return caches.open(cacheName).then((cache) => {
              cache.put(event.request.url, response.clone());
              return response;
            });
          });
        })
        .catch(async (error) => {
          console.log("Error fetching from cache", error);
        })
    );
  }
});

在添加了service_worker.js文件后,你需要将Service Worker添加到Web项目的index.html文件中。向index.html文件中添加以下代码:

<!DOCTYPE html>
<html>
  <head>
    <base href="$FLUTTER_BASE_HREF" />
    <meta charset="UTF-8" />
    <meta content="IE=Edge" http-equiv="X-UA-Compatible" />
    <meta name="description" content="A new Flutter project." />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <meta name="apple-mobile-web-app-title" content="example" />
    <link rel="apple-touch-icon" href="icons/Icon-192.png" />
    <link rel="icon" type="image/png" href="favicon.png" />
    <title>example</title>
    <link rel="manifest" href="manifest.json" />
    <!-- 添加以下代码以添加Service Worker -->
    <script>
      if ("serviceWorker" in navigator) {
        window.addEventListener("load", () => {
          navigator.serviceWorker
            .register("/service-worker.js")
            .then((registration) => {
              console.log("Service Worker :", registration);
            })
            .catch((error) => {
              console.log("Service Worker has Error:", error);
            });
        });
      }
    </script>
    <!-- Service Worker代码结束 -->
  </head>
  <body>
    <script src="flutter_bootstrap.js" async></script>
    <script src="main.dart.js" type="application/javascript"></script>
  </body>
</html>

完整示例

下面是完整的示例代码:

import 'package:cache_systems/cache_systems.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await CacheSystem().init(stalePeriod: const Duration(days: 7));
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Cache Systems Demo',
      home: MyHomePage(title: 'Cache Systems Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<CacheFile?> files = [];

  [@override](/user/override)
  void initState() {
    CacheSystem().getAllFile().then((value) {
      setState(() {
        files = value;
      });
    });

    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    final imgUri = Uri.parse(
      'https://fastly.picsum.photos/id/91/1500/1500.jpg?hmac=gFLcWG7TwMqsOm5ZizQJNJ2tYsENkSQdMMmNNp8Avvs',
    );
    return Scaffold(
      body: Column(
        children: [
          Expanded(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                // For Image
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    FutureBuilder<CacheFile?>(
                      future: CacheSystem().get(
                        imgUri,
                        fileType: CacheFileType.image,
                      ),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          return Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: Image.file(
                              snapshot.data!.file,
                              height: 100,
                              width: 100,
                            ),
                          );
                        }
                        return const SizedBox.shrink();
                      },
                    ),
                    // or use the CachedImage widget
                    CachedImage(url: imgUri, height: 100, width: 100),
                  ],
                ),
              ],
            ),
          ),
          Expanded(
            child: Column(
              children: [
                const Text('Cached Images'),
                Expanded(
                  child: GridView.builder(
                    gridDelegate:
                        const SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 3,
                    ),
                    itemCount: files.length,
                    itemBuilder: (context, index) {
                      final cachefile = files[index];
                      if (cachefile!.fileType != 'image/*') {
                        return const SizedBox.shrink();
                      }
                      return Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Image.file(
                          cachefile.file,
                          height: 100,
                          width: 100,
                        ),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter缓存管理插件cache_systems的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter缓存管理插件cache_systems的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter缓存管理插件cache_systems的使用,下面是一个简单的代码示例,展示了如何使用这个插件来管理应用的缓存。

首先,确保你已经在pubspec.yaml文件中添加了cache_systems依赖:

dependencies:
  flutter:
    sdk: flutter
  cache_systems: ^最新版本号  # 替换为当前最新版本号

然后,运行flutter pub get来安装依赖。

接下来,我们编写一个Flutter应用示例,展示如何使用cache_systems来缓存和检索数据。

import 'package:flutter/material.dart';
import 'package:cache_systems/cache_systems.dart';
import 'dart:convert';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CacheExample(),
    );
  }
}

class CacheExample extends StatefulWidget {
  @override
  _CacheExampleState createState() => _CacheExampleState();
}

class _CacheExampleState extends State<CacheExample> {
  final CacheSystems _cache = CacheSystems();
  String _cachedData = '';

  @override
  void initState() {
    super.initState();
    _fetchAndCacheData();
  }

  Future<void> _fetchAndCacheData() async {
    // 模拟从网络获取数据
    String fakeNetworkData = '{"message": "Hello, World!"}';

    // 将数据转换为JSON对象
    Map<String, dynamic> data = jsonDecode(fakeNetworkData);

    // 将数据缓存起来,使用键 'example_key'
    await _cache.save('example_key', data);

    // 从缓存中检索数据
    Map<String, dynamic> cachedData = await _cache.get<Map<String, dynamic>>('example_key');

    if (cachedData != null) {
      setState(() {
        _cachedData = cachedData['message'] ?? '';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cache Systems Example'),
      ),
      body: Center(
        child: Text(
          _cachedData,
          style: TextStyle(fontSize: 24),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          // 清除缓存
          await _cache.remove('example_key');

          // 重新获取并缓存数据
          await _fetchAndCacheData();
        },
        tooltip: 'Fetch Data',
        child: Icon(Icons.refresh),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 初始化CacheSystems实例:在_CacheExampleState类中创建了一个CacheSystems实例。
  2. 模拟数据获取:在_fetchAndCacheData方法中,我们模拟从网络获取数据,并将其转换为JSON对象。
  3. 缓存数据:使用_cache.save方法将数据缓存起来,键名为'example_key'
  4. 检索数据:使用_cache.get方法从缓存中检索数据,并将其显示在界面上。
  5. 清除缓存:提供了一个浮动按钮,点击后会清除缓存,并重新获取和缓存数据。

这个示例展示了如何使用cache_systems插件来缓存和检索数据。你可以根据自己的需求进一步扩展这个示例,例如处理网络请求、添加更多的缓存逻辑等。

回到顶部