0


【Flutter】使用Hive插件管理本地缓存与网络缓存

Hive的封装与实践

前言

之前的文章中我介绍过我的项目在缓存管理中还是使用的 path_provider 插件自行封装的缓存框架【传送门】。

本来是也是无伤大雅属于能用的状态,但是考虑到现在的除了网络请求的缓存,还有应用资源的缓存,导致大量的磁盘IO多少影响到性能,这里才想做出优化使用 Hive 接管应用的缓存。

Hive 也是天然适用于缓存这个场景,并且对比 path_provider 原始的方式有一些一些特点:

a) 数据结构和格式:

Hive使用自定义的二进制格式存储数据,这种格式经过优化,可以快速读写。 直接使用path_provider,你需要自己处理数据的序列化和反序列化。 b) 性能:

Hive针对快速读写进行了优化。它使用内存映射文件(memory-mapped files)来提高性能。 使用path_provider,性能取决于你如何实现文件读写。 c) API和易用性:

Hive提供了高级API,使得数据的存储和检索变得简单。 使用path_provider,你需要自己实现所有的数据管理逻辑。 d) 数据类型支持:

Hive支持多种数据类型,并且可以存储复杂对象。 使用path_provider,你需要自己处理不同数据类型的存储。 e) 加密:

Hive提供了内置的加密支持。 使用path_provider,你需要自己实现加密逻辑。 f) 事务和ACID属性:

Hive支持事务,保证了数据的一致性。 使用path_provider,你需要自己实现这些特性。

那么接下来我就详细的介绍一下并且封装之后进行实践。

一、Hive的介绍与使用

Hive 是一个为 Flutter 和 Dart 设计的轻量级、高性能的 NoSQL 数据库。它是用纯 Dart 编写的,不需要本地依赖,这使得它非常适合 Flutter 应用程序。让我为您详细介绍 Hive 并提供一些使用示例。

1.1 Hive 的主要特点:
  1. 快速:Hive 的读写操作非常快。
  2. 跨平台:支持所有 Flutter 平台。
  3. 类型安全:支持所有 Dart 原始类型、List、Map、DateTime 和 Uint8List。
  4. 轻量级:小巧简单,易于使用。
  5. 加密支持:可以加密 box 以保护敏感数据。
  6. 支持懒加载:可以打开巨大的 box,而不会影响启动时间。
  7. 支持事务
1.2 安装使用 Hive :

在你的 Flutter 项目的 pubspec.yaml 文件中添加依赖:

我们可以已使用 hive_flutter 的快速初始化,也可以自行初始化

或者

使用 Hive 的基本操作:

使用 Hive 进行 CRUD 操作的更多示例:

添加数据注意 add 和 put 的区别:

box.add(person):

这个方法会自动生成一个唯一的键(通常是一个自增的整数)。适用于你不需要指定特定键,只需要按顺序存储对象的情况。返回值是新添加对象的键。这种方法类似于在列表末尾添加一个新项。

box.put('key1', Person(...)):

这个方法允许你指定一个自定义的键(在这个例子中是 'key1')。如果指定的键已经存在,它会覆盖现有的值。适用于你需要使用特定键(如 ID、用户名等)来存储和检索对象的情况。不返回任何值。

当然在我们本地缓存这个场景还是 put 的方法更符合场景。

使用事务:

加密 box

二、Hive的封装与实践

问题来了,我们存储数据是KV的模式,那么是把 key 当做 box 的名称直接 add 一个 value 呢? 还是打开一个指定 name 的box 之后 put 对应的 key 和 value 呢?

再者是我们每次调用都需要打开一个 box 是否方便,是否需要封装使用如何封装?

其实这取决于你的具体需求和数据结构。两种方法都有其适用场景:

a. 把 key 当做 box 的名称,直接 add 一个 value:

优点:简单直接,适合存储单一类型的数据集合。

缺点:可能会创建大量的 box,不利于管理。

适用场景:例如,每个用户一个 box,存储该用户的所有相关数据。

b. 打开一个指定 name 的 box,然后 put 对应的 key 和 value:

优点:更灵活,可以在一个 box 中存储多种类型的数据,便于管理。

缺点:需要自己管理 key 的唯一性。

适用场景:存储应用程序的各种设置,或者同一类型的多个对象。

我个人认为两种都太极端,一个是 Box 太多显著的影响性能,二是 Box 太大也影响读取查询性能。我个人认为应该是按模块分 box ,并且集中管理封装单例 box 对象,例如我们分为 http_cache, app_cache,log_cache 等 固定的 box 名称,用枚举定义,每次打开不同的 Box 之后用单例保存其对象,拿到不同的 box 之后进行对应空间内部的 CURD 则更完美,也更符合”蜂巢“这个概念。

存入:

取出:

日志:

测试带缓存的存入:

测试缓存的取出

我们存入之后立马取出,然后等10秒之后再取一次,日志如下:

比较特殊的是对象的存储,例如:

如果直接存储还是会报错的,因为对象的存储还是需要你自行填写数据适配器并注册到 Hive 中,这里参考 Hive 的文档实现即可:

三、网络请求缓存的实战

得益于我们之前的 Dio 网络请求实战中的封装,我们对于本地缓存的引擎封装只需要替换对应的引擎实现即可。具体可参考我之前的文章【传送门】

我们在 Dio 的缓存拦截器中实现如下:

把存入缓存和取出缓存的换为我们的 localCache 对象即完成修改,注意这里的网络请求我们默认是存入的 app_cache 的 box 中,如果有需求可以自定义容器或者指定容器。

使用的时候我们只需要开启缓存。

结果:

总结

本文介绍了 Hive 的简单使用,以及对应的封装和应用场景的示例,可以看到是可以完全平替 path_provider 的缓存框架的。

总的来说,Hive是一个更高级的解决方案,它在 path_provider 的基础上提供了许多额外的功能和优化。虽然两者都涉及磁盘IO,但Hive提供了更多的抽象和优化,并且内部有内存优化使得数据存储和检索更加快速高效和方便。

在实际开发中,如果你的数据存储需求简单,使用

path_provider

直接操作文件可能足够。但如果你需要一个高效、可扩展、易于管理的解决方案,Hive 是一个更好的选择。

如果对详细的代码有兴趣,也可以参考我的开源项目 【Flutter Room】。

那么今天的分享就到这里啦,当然如果你有其他的更多的更好的实现方式,也希望大家能评论区交流一起学习进步。如果我的文章有错别字,不通顺的,或者代码、注释、有错漏的地方,同学们都可以指出修正。

如果感觉本文对你有一点的启发和帮助,还望你能

点赞

支持一下,你的支持对我真的很重要。

Ok,这一期就此完结。

原文链接:https://juejin.cn/post/7412672643633823807

标签: flutter hive 缓存

本文转载自: https://blog.csdn.net/weixin_47588164/article/details/142090790
版权归原作者 码农巧克零 所有, 如有侵权,请联系我们删除。

“【Flutter】使用Hive插件管理本地缓存与网络缓存”的评论:

还没有评论