Flutter鸿蒙next 状态管理框架对比分析
在 Flutter 开发中,状态管理是一个非常重要且关键的主题。Flutter 中的应用状态管理直接影响着应用的性能、可维护性和开发效率。随着 Flutter 生态的成熟,已经出现了许多不同的状态管理方案,各具特色,适用于不同的开发场景。本文将对 Flutter 中常见的几种状态管理框架进行对比分析,并给出详细的代码解释。
1. 状态管理框架概述
在 Flutter 中,状态管理可以分为两类:局部状态管理和全局状态管理。
- 局部状态管理:适用于只在某个小范围内的组件或页面中共享的状态。常见的方式有
setState()
、InheritedWidget
和Provider
等。 - 全局状态管理:适用于整个应用中多个页面或组件共享的状态。常见的方式有
Provider
、Riverpod
、Bloc
、Redux
和GetX
等。
2. 常见状态管理框架
2.1 setState()
setState()
是 Flutter 中最简单的一种状态管理方式。它是局部状态管理的一部分,主要用于更新当前 Widget 的状态。当需要改变状态时,调用 setState()
并更新状态,然后 Flutter 会重新构建 Widget。
优点:
- 简单直接,适用于单一组件的状态变化。
- 内置支持,无需额外的库。
缺点:
- 只能管理局部状态,无法应对复杂的状态逻辑。
- 不适合全局状态的管理。
2.2 InheritedWidget
InheritedWidget
是一种更为底层的状态管理方式,它通过 Widget 树的继承机制将数据传递给子 Widget。InheritedWidget
适用于需要在多个 Widget 之间共享状态的场景。
优点:
- 适合复杂的数据传递。
- 支持跨越多个 Widget 层级共享数据。
缺点:
- 使用起来较为复杂,需要手动实现数据更新逻辑。
- 可能导致性能问题,尤其是在频繁更新的情况下。
2.3 Provider
Provider
是 Flutter 中目前最常用的状态管理方案之一,它基于 InheritedWidget
实现,封装了更高层次的 API,提供了更便捷的使用方式。Provider
的核心思想是通过依赖注入来管理和共享状态。
优点:
- 简单易用,且功能强大。
- 支持全局和局部状态管理。
- 性能良好,避免了不必要的重绘。
缺点:
- 当涉及到复杂的状态和数据流时,可能需要更多的代码来管理。
2.4 Riverpod
Riverpod
是由 Provider
的作者创建的新一代状态管理框架。它的核心理念是通过 Provider
提供更灵活的方式来管理应用状态,支持更加细粒度的控制。
优点:
- 比
Provider
更强大和灵活,支持更多的功能,如组合不同的 Provider。 - 自动缓存,提高了性能。
缺点:
- 学习曲线稍高。
- 需要适应新的编程范式,和
Provider
有一定的差异。
2.5 Bloc
BLoC
(Business Logic Component)是一种更加结构化的状态管理方式,它将业务逻辑从 UI 中分离,使用流(Streams)来管理数据流动。BLoC
适合大型应用的开发,尤其是当应用逻辑复杂时。
优点:
- 提供了清晰的代码结构,易于测试。
- 对于大型应用程序非常有效,尤其适合与 RxDart 配合使用。
缺点:
- 相较于
Provider
和Riverpod
,代码更为复杂。 - 学习曲线较高。
2.6 GetX
GetX
是一个相对较新的状态管理框架,它的设计目标是简化开发过程,提供更简单的状态管理、更强的依赖注入和路由管理功能。
优点:
- 简单易用,代码简洁。
- 内存占用低,性能优异。
- 支持响应式编程。
缺点:
- 不如
Provider
和Riverpod
成熟,可能出现一些不稳定的情况。 - 不太符合 Flutter 官方推荐的编程范式。
3. 状态管理方案对比
特性 | setState() | InheritedWidget | Provider | Riverpod | BLoC | GetX |
---|---|---|---|---|---|---|
学习曲线 | 低 | 中 | 中 | 高 | 高 | 低 |
简单性 | 简单 | 较复杂 | 简单 | 中 | 高 | 非常简单 |
适用场景 | 局部状态管理 | 跨层级共享数据 | 局部与全局 | 全局状态管理 | 复杂业务逻辑 | 简单与中等状态管理 |
性能 | 较差 | 较差 | 良好 | 优秀 | 优秀 | 非常优秀 |
易于测试 | 低 | 中 | 高 | 高 | 高 | 中 |
4. 示例代码分析:Provider
的使用
代码示例
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';// 定义一个模型类,用于保存计数的状态
class Counter with ChangeNotifier {int _count = 0;int get count => _count;void increment() {_count++;notifyListeners(); // 通知所有监听者更新}
}void main() {runApp(ChangeNotifierProvider(create: (context) => Counter(), // 提供 Counter 的实例child: MyApp(),),);
}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(home: HomeScreen(),);}
}class HomeScreen extends StatelessWidget {@overrideWidget build(BuildContext context) {// 使用 Consumer 监听状态变化return Scaffold(appBar: AppBar(title: Text('Provider Example')),body: Center(child: Consumer<Counter>(builder: (context, counter, child) {return Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('Button pressed ${counter.count} times'),ElevatedButton(onPressed: counter.increment,child: Text('Increment'),),],);},),),);}
}
代码解析
-
模型类(
Counter
):
这个类用于保存应用状态,并继承了ChangeNotifier
。ChangeNotifier
是 Flutter 中用于管理和通知状态变化的基类。每当increment
方法被调用时,通过notifyListeners()
方法通知所有监听者(例如 UI)更新状态。 -
ChangeNotifierProvider
:ChangeNotifierProvider
是Provider
提供的一个 Widget,它会创建并管理Counter
的实例,确保在整个 Widget 树中都可以访问到Counter
对象。ChangeNotifierProvider
通常是包裹在应用的根 Widget 中,确保所有需要访问该状态的子 Widget 都可以访问到它。 -
Consumer
:Consumer
是一个非常强大的 Widget,用于监听和响应状态变化。它会自动监听Counter
实例中的状态变化,并在状态改变时重新构建其子树。在这里,Consumer
的builder
会在每次状态变化时调用,更新 UI 显示的计数值。 -
按钮与状态更新:
按钮的点击事件会触发increment()
方法,从而更新计数器的值。通过notifyListeners()
,UI 会根据状态的变化自动重新构建并显示新的计数值。
5. 总结
在选择合适的状态管理框架时,需要考虑应用的复杂度、团队的熟悉程度以及对性能的要求。对于简单的应用,setState()
和 Provider
已经足够;对于复杂的应用,Riverpod
和 BLoC
可能更为合适。GetX
则在简洁和高性能方面有其独特的优势。
无论选择哪个框架,理解其工作原理和最佳实践都是确保应用成功的关键。
相关文章:

Flutter鸿蒙next 状态管理框架对比分析
在 Flutter 开发中,状态管理是一个非常重要且关键的主题。Flutter 中的应用状态管理直接影响着应用的性能、可维护性和开发效率。随着 Flutter 生态的成熟,已经出现了许多不同的状态管理方案,各具特色,适用于不同的开发场景。本文…...

Vue Router进阶详解
导航守卫 若依框架登录鉴权详解(动态路由)_若依鉴权-CSDN博客 完整的导航解析流程 导航被触发: 当用户点击页面中的链接、使用编程式导航(如router.push或router.replace)或手动输入URL时,导航流程被触发。…...

进程的控制
进程 task_struct mm_struct(虚拟地址空间) 页表 代码和数据 。 新建进程先有管理系统,然后才有代码和数据。 fork()函数:子进程返回0,父进程返回的是子进程的pid - - - 方便父进程对子进程标识。 进程终止:释放代码和数据占…...

基于C语言实现的图书管理系统
使用Visual Studio 2022编译工具进行编写代码的。 项目源码直接奉上: book1.h头文件: #ifndef __BOOK1_H //预处理用于条件编译 避免头文件反复包含 #define __BOOK1_H#include<stdio.h> #include <string.h> #include<stdlib.h> #include<stdbool.h&g…...

删除 需要来自XXXX的权限才能对此文件夹进行更改 文件的解决办法
如果你也是: 如果你也有类似上面的问题,这篇文章算是你看对了,哦哟! 我的牙齿现在是怨灵的牙齿,可以啃下一头牛。 翻遍千山万水,咱们也是终于取到真经了家人们。 首先下一个everything好吗 甩一个官网链…...

ARM base instruction -- ccmp (immediate)
Conditional Compare (immediate) sets the value of the condition flags to the result of the comparison of a register value and an immediate value if the condition is TRUE, and an immediate value otherwise. 此指令一般出现在 cmp 指令之后,表示双重比…...

高德 阿里231滑块 分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 有相关问题请第一时间头像私信联系我删…...

Unity 的 WebGL 构建中资源图片访问方式
在 Unity 的 WebGL 构建中,资源图片是可以打包在 工程内部 使用的,前提是这些资源被正确地包含在构建中,并且能够通过合适的方式加载和访问。不同于传统的本地文件访问,WebGL 需要通过 Asset Bundles、Addressables 或 Resources …...

WinForms 中使用 MVVM 模式构建应用:实现登录页面、页面导航及 SQLite 数据库连接完整框架搭建过程
前言 在传统的 WinForms 应用程序开发中,很多开发者使用事件驱动的设计模式,直接将业务逻辑编写在界面代码中。然而,随着应用程序的复杂性增加,单一的界面文件变得臃肿,难以测试和维护。借鉴 WPF 中 MVVM(…...

Chrome调试工具(查看CSS属性)
来说说这个Chrome调试工具吧,梦回gdb,但是它没有gdb难 打开浏览器 有两种方式可以直接打开Chrome调试工具 直接按F12 鼠标右键页面 --- 检查元素 什么mc玩家是鸣潮 标签页含义 🤒 elements查看标签结构(展示html文件&#…...

MQTT从入门到精通之MQTT入门
MQTT入门 1 MQTT概述 1.1 MQTT简介 MQTT(Message Queuing Telemetry Transport)由IBM于1999年开发的一种基于**"发布订阅模式"的轻量级的消息传输协议**! 发布订阅模式是一种传统的客户端-服务器架构的替代方案,因为…...

Hadoop生态系统主要包括哪些组件以及它们的作用
Hadoop生态系统是一个开源的大数据处理框架,它主要由一系列组件构成,每个组件都承担着不同的功能和作用。以下是Hadoop生态系统的主要组件及其作用的详细解释: HDFS(Hadoop Distributed File System) 作用:…...

OpenResty 1.27.1.1 已经正式发布
OpenResty 1.27.1.1 已经正式发布,这是一个基于 NGINX 和 LuaJIT 的 web 平台。以下是关于此次发布的一些重点信息和更新内容: 下载与安装 你可以在此处下载最新版本的 OpenResty。提供了便携式源代码分发、Win32/Win64 二进制分发以及为 Ubuntu、Debi…...

定高虚拟列表:让大数据渲染变得轻松
定高虚拟列表 基本认识 在数据如潮水般涌来的今天,如何高效地展示和管理这些数据成为了开发者们面临的一大挑战,传统的列表渲染方式在处理大量数据时,往往会导致页面卡顿、滚动不流畅等问题,严重影响用户体验(在页面…...

python request与grequests该如何选择
requests & grequests requests 和 grequests 是Python中用于发送HTTP请求的不同库。requests 是一个同步、阻塞式库,而 grequests 是基于 requests 封装的异步非阻塞库,它利用了 gevent 库提供的协程机制,能够并发发送多个请求。 选择…...

Unity3D UI 拖拽
Unity3D 实现 UI 元素拖拽功能。 UI 拖拽 通常画布上的 UI 元素都是固定位置的,我们可以通过实现拖拽接口,让 UI 元素可以被拖拽到其他位置。 拖拽接口 创建一个脚本 UIDrag.cs,在默认继承的 MonoBehaviour 后面,再继承三个接…...

介绍一下memcpy(c基础)
memcpy函数void *memcpy(void *dest, const void *src, size_t n); dest:指向目标内存区域的指针,即复制的目的地。src:指向源内存区域的指针,即要被复制的内容的来源。n:要复制的字节数 主要功能是将src所指向的内存…...

【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
目录 一、相关面试题 1. HTTP 与 HTTPS 有哪些区别? 2. HTTPS 的工作原理?(https 是怎么建立连接的) (1)ClientHello (2)SeverHello (3)客户端回应 &a…...

python-23-一篇文章帮你理解Python推导式
python-23-一篇文章帮你理解Python推导式 一.简介 在 Python 中,推导式(Comprehensions)是一个简洁的语法,用于通过某种可迭代对象快速生成新的对象(如列表、字典、集合等!来开始我们今天的日拱一卒&…...

WPF中如何简单的使用CommunityToolkit.Mvvm创建一个项目并进行 增删改查
目录 开始前准备的数据库dbblog如下: 第一步:创建项目后下载四个NuGet程序包 第二步:删除原本的MainWindow.XAML文件 并创建如下的目录结构 然后在View文件夹下面创建Login.XAML和Main.XAML 并且在App.XAML中将启动项改为Login.X…...

CesiumJS 案例 P15:检测标记、鼠标点击移动标记、鼠标拖动标记
CesiumJS CesiumJS API:https://cesium.com/learn/cesiumjs/ref-doc/index.html CesiumJS 是一个开源的 JavaScript 库,它用于在网页中创建和控制 3D 地球仪(地图) 一、检测标记 <!DOCTYPE html> <html lang"en&…...

Webserver(4.9)本地套接字的通信
目录 本地套接字 本地套接字 TCP\UDP实现不同主机、网络通信 本地套接字实现本地的进程间的通信,类似的,一般采用TCP的通信流程 生成套接字文件 #include<arpa/inet.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h&…...

[IAA系列] Image Aesthetic Assessment
Preface 本文旨在记录个人结合AI工具对IAA这个领域的一些了解,主要是通过论文阅读的方式加深对领域的了解。有什么问题,欢迎在评论区提出并讨论。 什么是IAA Image Aesthetic Assessment(图像美学评估)是一种评估图像在视觉上的…...

基于springboot的高校科研管理系统(源码+调试+LW)
项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据你想解决的问题,今天给…...

Flutter环境配置
配置环境变量 PUB_HOSTED_URLhttps://pub.flutter-io.cn FLUTTER_STORAGE_BASE_URLhttps://storage.flutter-io.cn 这个命令是用来配置 Flutter 的镜像源地址,主要是为了解决在中国大陆地区访问 Flutter 官方资源较慢的问题 具体的操作做如下: 右键点击"此…...

Rip动态路由及Rip动态路由优化
动态路由Rip Tip:Rip动态路由实现多个路由间不同网段通信。 本次实验目的,通过给ar1,ar2,ar3配置rip动态路由,实现pc1 ping通 pc2。 AR1配置如下: <Huawei>sy Enter system view, return user view with CtrlZ. [Huawei]…...

双路快速排序和三路排序算法
双路快速排序 一、概念及其介绍 双路快速排序算法是随机化快速排序的改进版本,partition 过程使用两个索引值(i、j)用来遍历数组,将 <v 的元素放在索引i所指向位置的左边,而将 >v 的元素放在索引j所指向位置的…...

SQL server增删改查语句和实例
在 SQL Server 中,增删改查操作分别对应 INSERT、DELETE、UPDATE 和 SELECT 语句。以下是具体介绍及实例: 一、插入数据(INSERT) 语法: INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, val…...

强化学习_06_pytorch-PPO2实践(ALE/Breakout-v5)
一、环境适当调整 数据收集:RecordEpisodeStatistics进行起始跳过n帧:baseSkipFrame一条生命结束记录为done:EpisodicLifeEnv得分处理成0或1:ClipRewardEnv叠帧: FrameStack 图像环境的基本操作,方便CNN捕捉智能体的行动 向量空间reset处理修…...

《JVM第8课》垃圾回收算法
文章目录 1.标记算法1.1 引用计数法1.2 可达性分析法 2.回收算法2.1 标记-清除算法(Mark-Sweep)2.2 复制算法(Coping)2.3 标记-整理算法(Mark-Compact) 3.三种垃圾回收算法的对比 为什么要进行垃圾回收&…...