当前位置: 首页 > news >正文

Flutter_学习记录_状态管理之GetX

1. 状态管理、Flutter Getx介绍

1.1 状态管理

通俗的讲:当我们想在多个页面(组件/Widget)之间共享状态(数据),或者一个页面(组件/Widget)中的多个子组件之间共享状态(数据),这个时候我们就可以用Flutter中的状态管理来管理统一的状态(数据),实现不同组件之间的传值和数据共享。

现在Flutter的状态管理方案很多:redux、bloc、state、provider、Getx

provider是官方提供的状态管理解决方案,主要功能就是状态管理。
Getx是第三方的状态管理插件,不仅具有状态管理的功能,还具有路由管理、主题管理、国际化多语言管理、Obx局部更新、网络请求、数据验证等功能,相比其他状态管理插件Getx 简单、功能强大并且高性能。

1.2、Flutter Getx介绍

GetX 是 Flutter 上的一个轻量且强大的解决方案,Getx为我们提供了高性能的状态管理、智能的依赖注入和便捷的路由管理。

GetX 有3个基本原则

  • 性能: GetX 专注于性能和最小资源消耗。GetX 打包后的apk占用大小和运行时的内存占用与其他状态管理插件不相上下。
  • 效率: GetX 的语法非常简捷,并保持了极高的性能,能极大缩短你的开发时长。
  • 结构: GetX 可以将界面、逻辑、依赖和路由完全解耦,用起来更清爽,逻辑更清晰,代码更容易维护

GetX 并不臃肿,却很轻量。如果只使用状态管理,只有状态管理模块会被编译,其他没用到的东西都不会被编译到代码中。它拥有众多的功能,但这些功能都在独立的容器中,只有在使用后才会启动。

Getx有一个庞大的生态系统,能够在Android、iOS、Web、Mac、Linux、Windows和你的服务器上用同样的代码运行。 通过Get Server 可以在你的后端完全重用你在前端写的代码。

2. GetX 的简单使用

2.1 项目中集成GetX

官网:https://pub.dev/packages/get
中文文档:https://github.com/jonataslaw/getx/blob/master/README.zh-cn.md

添加 GetX 的插件

在这里插入图片描述

导入头文件

import 'package:get/get.dart';

mian.dart 的文件中,将主入口的 MaterialApp 修改成GetMaterialApp

import 'package:flutter/material.dart';
import 'package:get/get.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {//  `MaterialApp` 修改成`GetMaterialApp`return  GetMaterialApp(debugShowCheckedModeBanner: true,home: Home(),theme: ThemeData(appBarTheme: AppBarTheme(backgroundColor: Colors.yellow,)),);}
}

2.2 显示GetX 默认的弹框defaultDialog

void _getXDefaultDialog() {Get.defaultDialog(title: "默认弹窗",middleText: "弹窗的内容",cancel: ElevatedButton(onPressed: (){Get.back();}, child: Text("取消")),confirm: ElevatedButton(onPressed: (){Get.back();}, child: Text("确认")),radius: 15.0);}

Dialog属性和说明
在这里插入图片描述

2.3 显示GetX Snackbar

void _getXSnackbar() {Get.snackbar("提示标题", "提示内容", snackPosition: SnackPosition.BOTTOM,borderRadius: 10.0);}

Snackbar属性和说明

在这里插入图片描述
在这里插入图片描述

2.4 显示GetX BottomSheet

void _getXBottomSheet() {Get.bottomSheet(Container(color: Get.isDarkMode ? Colors.white12 :  Colors.white,height: 200,child: Column(children: [ListTile(onTap: (){// 改变主题模式Get.changeTheme(ThemeData.light());Get.back();},leading: Icon(Icons.sunny_snowing),title: Text("白天模式", style: TextStyle(color: Get.isDarkMode ? Colors.white : Colors.black),),),ListTile(onTap: (){// 改变主题模式Get.changeTheme(ThemeData.dark());Get.back();},leading: Icon(Icons.dark_mode),title: Text("黑夜模式", style: TextStyle(color: Get.isDarkMode ? Colors.white : Colors.black)),)],),));}

BottomSheet属性和说明
在这里插入图片描述

2.5 用GetX 修改主题模式

// 将主题修改成黑夜模式
Get.changeTheme(ThemeData.dark());
// 将主题修改成白天模式
Get.changeTheme(ThemeData.light());

3. GetX 的路由管理

3.1 Flutter Getx 配置路由以及动画

class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return  GetMaterialApp(debugShowCheckedModeBanner: true,// home: Home(),theme: ThemeData(appBarTheme: AppBarTheme(backgroundColor: Colors.yellow, // 设置导航栏颜色为蓝色)),// 设置初始化页面initialRoute: "/",// 设置路由信息getPages:[GetPage(name: "/", page:  () => Home()),GetPage(name: "/login", page: () => GetLoginDemo()),GetPage(name: "/register", page: () => GetRegisterDemo()),GetPage(name: "/shop", page: () => GetShopDemo()),GetPage(name: "/shopMiddle", page: () => GetShopDemo(), middlewares: [GetShopmiddlewareDemo()]),] ,// 设置跳转动画defaultTransition: Transition.rightToLeft,);}
}

代码解读

  • getPages 是一个数组,里面放着 GetPage类型的对象,name表示路由的名字, page 表示跳转的页面
  • initialRoute表示初始化的页面
  • defaultTransition 表示页面跳转的动画效果

3.2 GetX 跳转的常见方法:

调用to方法切换路由

Get.to(Home());

调用Get.toNamed()跳转到命名路由

// 不带参数的跳转
Get.toNamed("/login");
// 带参数的跳转
Get.toNamed("/shop",arguments: { "id":20 
});

Getx 路由跳转传值以及接受数据

路由配置

	getPages:[GetPage(name: "/shop", page: () => GetShopDemo())]

跳转传值

Get.toNamed("/shop", arguments: {"id": 111111});

Get.back(); 返回到上一级页面

Get.back();

Get.offAll(); 返回到根

Get.offAll(Home());

进入下一个页面,但没有返回上一个页面的选项(用于闪屏页,登录页面等):Get.off(NextScreen());

3.3 Getx 中间件配置

新建一个Get_ShopMiddleware_demo.dart文件


import 'dart:math';import 'package:flutter/src/widgets/navigator.dart';
import 'package:get/get.dart';class  GetShopmiddlewareDemo extends GetMiddleware {//  重写跳转页面,例如点击购物,但是如果没有登录,就直接跳转登录页面;登录了就跳转商品页面RouteSettings? redirect(String? route) {print("redirect");int randomIndex = Random().nextInt(3);if (randomIndex == 1) {return super.redirect(route); } else {return RouteSettings(name: "/login");}}
}

GetPage配置路由,在 middlewares 中添加中间件

// 设置路由信息getPages:[GetPage(name: "/shopMiddle", page: () => GetShopDemo(), middlewares: [GetShopmiddlewareDemo()]),]

使用

 Get.toNamed("/shopMiddle", arguments: {"id": 111111
});

4.Flutter Getx 状态管理

4.1 状态管理

目前,Flutter有几种状态管理器。但是,它们中的大多数都涉及到使用ChangeNotifier来更新widget,

这对于中大型应用的性能来说是一个很糟糕的方法。在Flutter的官方文档中查看到,ChangeNotifier应该使用1个或最多2个监听器,这使得它们实际上无法用于任何中等或大型应用

Get 并不是比任何其他状态管理器更好或更差,而是说分析这些要点以及下面的要点来选择只用Get,还是与其他状态管理器结合使用。

Get不是其他状态管理器的敌人,因为Get是一个微框架,而不仅仅是一个状态管理器,既可以单独使用,也可以与其他状态管理器结合使用。

Get有两个不同的状态管理器:响应式状态管理器、简单的状态管理器。

4.2 响应式状态管理器的使用

这部分的写作,参考的是这个文章:https://juejin.cn/post/7020598013986865182

4.2.1 声明响应式变量

  1. 使用 Rx{Type}
// 建议使用初始值,但不是强制性的
final name = RxString('');
final isLogged = RxBool(false);
final count = RxInt(0);
final balance = RxDouble(0.0);
final items = RxList<String>([]);
final myMap = RxMap<String, int>({});
  1. 使用 Rx规定泛型 Rx
final name = Rx<String>('');
final isLogged = Rx<Bool>(false);
final count = Rx<Int>(0);
final balance = Rx<Double>(0.0);
final number = Rx<Num>(0)
final items = Rx<List<String>>([]);
final myMap = Rx<Map<String, int>>({});
// 自定义类 - 可以是任何类
final user = Rx<User>();

3、这种更实用、更简单、更可取的方法,只需添加 .obs 作为value的属性。(推荐使用)

final name = ''.obs;
final isLogged = false.obs;
final count = 0.obs;
final balance = 0.0.obs;
final number = 0.obs;
final items = <String>[].obs;
final myMap = <String, int>{}.obs;
// 自定义类 - 可以是任何类
final user = User().obs;

4.2.2 自定义类的使用

第一种自定义类的使用:定义包含Rx属性的自定义类

// 1. 定义一个包含Rx属性的类型
class Person {RxString userName;RxInt age;Person({required this.userName, required this.age});
}// 2. 声明变量
final Person _person = Person(userName: "猪猪".obs, age: 20.obs);// 3. 使用
ListTile(// 用 Obx() 来更新局部的UItitle: Obx((){return Text("person-姓名:${_person.userName}");}),
),// 4. 改变数据:改变Person 的姓名字段
_person.userName.value = "${_person.userName} + 拼接$_count";

第二种自定义类的使用:常规属性的自定义类

// 1. 定义一个常规属性的自定义类
class Animal {String kindName;int count;Animal({required this.kindName, required this.count});
}// 2. 声明变量
final Rx<Animal> _animal = Animal(kindName: "小猫", count: 1).obs;// 3. 使用
ListTile(
// 用 Obx() 来更新局部的UItitle: Obx((){return Text("animal-动物名:${_animal.value.kindName}");}),
)// 4. 改变数据:改变Animal 的种类字段
_animal.value.kindName =  "${_animal.value.kindName} + 拼接$_count";
_animal.refresh();

4.2.3 完整案例

import 'package:flutter/material.dart';
import 'package:get/get.dart';class GetDatastatusDemo extends StatefulWidget {const GetDatastatusDemo({super.key});State<GetDatastatusDemo> createState() => _GetDatastatusDemoState();
}class _GetDatastatusDemoState extends State<GetDatastatusDemo> {// 1.1 定义int类型的数据final RxInt _count = 0.obs;// 2.1 定义String类型的数据final RxString _titleString = "这是字符串".obs;// 3.1 定义List<String> 类型的数据final List<String> _listString = ["1", "2"].obs;// 4.1 定义一个内部带有obs数据的模型final Person _person = Person(userName: "猪猪".obs, age: 20.obs);// 5.1 定义一个常规的模型final Rx<Animal> _animal = Animal(kindName: "小猫", count: 1).obs;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("数据的状态管理"),),body: ListView(children: [ListTile(// 1.2 用 Obx() 来更新局部的UItitle: Obx((){return Text("count: ${_count.value}");}),),ListTile(// 2.2 用 Obx() 来更新局部的UItitle: Obx((){return Text("字符串:$_titleString");}),),ListTile(// 3.2 用 Obx() 来更新局部的UItitle: Obx((){return Text("字符串:${_listString.toString()}");}),),ListTile(// 4.2 用 Obx() 来更新局部的UItitle: Obx((){return Text("person-姓名:${_person.userName}");}),),ListTile(// 5.2 用 Obx() 来更新局部的UItitle: Obx((){return Text("animal-动物名:${_animal.value.kindName}");}),),],),floatingActionButton: FloatingActionButton(onPressed: (){// 1.3 改变数据_count.value ++;// 2.3 改变数据_titleString.value = "$_titleString + 拼接$_count";// 3.3 改变数据_listString.add("拼接$_count");// 4.3 改变Person 的姓名字段_person.userName.value = "${_person.userName} + 拼接$_count";// 5.3 改变Animal 的种类字段_animal.value.kindName =  "${_animal.value.kindName} + 拼接$_count";_animal.refresh();},child: Icon(Icons.add),),);}
}//-------定义一个内部变量为obs类型的模型类
class Person {RxString userName;RxInt age;Person({required this.userName, required this.age});
}//-------定义一个常规模型
class Animal {String kindName;int count;Animal({required this.kindName, required this.count});
}

4.2.4 效果图如下:

在这里插入图片描述

4.3 Flutter Getx 简单的状态管理(依赖管理) GetxController 和 Binding

4.3.1 Getx 依赖管理简介

Get有一个简单而强大的依赖管理器,它允许你只用1行代码就能检索到与你的Bloc或Controller相同的类,无需Provider context,无需inheritedWidget。

Controller controller = Get.put(Controller());

Get会自动找到想要的数据,甚至不需要任何额外的依赖关系。

Controller controller = Get.find(); 
//是的,它看起来像魔术,Get会找到你的控制器,并将其提供给你。你可以实例化100万个控制器,Get 总会给你正确的控制器。

4.3.2 Binding

在我们使用 GetX 状态管理器的时候,往往每次都是用需要手动实例化一个控制器,这样的话基本页面都需要实例化一次,这样就太麻烦了,而 Binding 能解决上述问题,可以在项目初始化时把所有需要进行状态管理的控制器进行统一初始化,简单介绍一下几个最常用的:

Get.put(): 不使用控制器实例也会被创建
Get.lazyPut(): 懒加载方式创建实例,只有在使用时才创建
Get.putAsync(): Get.put() 的异步版版本
Get.create(): 每次使用都会创建一个新的实例

4.3.3 用GetxController 和 Binding 结合的使用

  1. 创建一个继承GetxController的控制器Countcontroller
import 'package:get/get.dart';class Countcontroller extends GetxController {var count = 0.obs;void increase() {count++;// 需要调用update来通知更新update();}void decrease() {if (count > 1) {count--;}// 需要调用update来通知更新update();}
}
  1. 创建一个 实现Bindings 的控制器Bindcontroller
import 'package:demoapp/Demo/Get/CountController.dart';
import 'package:get/get.dart';class Bindcontroller implements Bindings {void dependencies() {//  用 lazyPut 关联 CountcontrollerGet.lazyPut<Countcontroller>(() => Countcontroller());} 
}
  1. 在程序的入口(程序入口,需要将MaterialApp 修改成GetMaterialApp, 前面已经提到了),用initialBinding初始化Bindcontroller的值
import 'package:demoapp/Demo/Get/BindController.dart';
import 'package:demoapp/Router/AppRouter.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return  GetMaterialApp(debugShowCheckedModeBanner: true,// home: Home(),theme: ThemeData(appBarTheme: AppBarTheme(backgroundColor: Colors.yellow, // 设置导航栏颜色为蓝色)),// 设置初始化页面initialRoute: "/",// 设置路由信息getPages: Approuter.appRouterPages() ,// 设置跳转动画defaultTransition: Transition.rightToLeft,// 绑定控制器initialBinding: Bindcontroller(),);}
}
  1. 创建两个页面,来实现 页面数据的共享。
    功能:第一个页面获取到第二个页面的数据

第一个页面:

import 'package:demoapp/Demo/Get/CountController.dart';
import 'package:demoapp/Router/AppRouter.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';class GetEasystatusDemo extends StatelessWidget {//  Get.find() 来找到共享的数据的页面,因为用了Bind 懒加载lazyput 所以不会出问题final Countcontroller _countCtr = Get.find();GetEasystatusDemo({super.key});// getX 简单式数据管理void _getXEasyDataStatus() {// 用Get.toName 进行页面的跳转,Approuter.getEasyStatueTwoName 是抽取出来的页面的名字的定义,方便使用Get.toNamed(Approuter.getEasyStatueTwoName);}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("简单的状态管理"),),body: Center(child: Padding(padding: EdgeInsets.all(5),child: Row(mainAxisAlignment: MainAxisAlignment.center,spacing: 20.0,children: [ElevatedButton(onPressed: _getXEasyDataStatus, child: Text("简单状态管理")),// 用obx 来刷新局部数据Obx((){ return Text("count = ${_countCtr.count}"); })],),)),);}
}

第二页页面:

import 'package:demoapp/Demo/Get/CountController.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';class GetEasystatusSecondDemo extends StatelessWidget {//  Get.find() 来找到共享的数据的页面,因为用了Bind 懒加载lazyput 所以不用重新调用Get.put()方法final Countcontroller _countCtr = Get.find();GetEasystatusSecondDemo({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("简单的状态管理"),),body: Center(child: Obx((){return Text("count = ${_countCtr.count}");})),floatingActionButton: FloatingActionButton(onPressed: (){// 让count +1_countCtr.increase();},child: Icon(Icons.add),),);}
}

4.3.4 效果图如下

在这里插入图片描述

4.4 GetView 和 GetXController 和 Bindings 的结合使用

4.4.1 GetView 的介绍

GetView 只是对已注册的 Controller 有一个名为 controller 的getter的 const Stateless 的 Widget如果我们只有单个控制器作为依赖项,那我们就可以使用 GetView而不是使用StatelessWidget ,并且避免了写 Get.Find()

4.4.2 GetView 和 GetXController 和 Bindings结构的分析

  • GetView 主要是专注于页面的搭建和UI的更新
  • GetXController 主要是用于抽离数据, 维护和更新数据
  • Bindings 主要是懒加载GetXController,避免写Get.put(),让代码比较优雅

4.4.3 GetView 和 GetXController 和 Bindings 案例的使用

  1. 新建一个维护数据的GetXController
import 'package:get/get.dart';class ShopController extends GetxController {RxList dataList = [].obs;void onInit() {print("onInit");super.onInit();getDataRequest();}void onClose() {print("onClose");super.onClose();}void getDataRequest() {dataList.add("新增数据");}
}
  1. 新建一个Bindings 的类
import 'package:demoapp/Demo/Get/Controller/ShopController.dart';
import 'package:get/get.dart';class ShopBindings implements Bindings {void dependencies() {Get.lazyPut<ShopController>(() => ShopController());}
}
  1. 新建一个GetView的页面类:
    3.1 需要集成于: GetView
    3.2 需要关联:<ShopController>
    3.3 用 controller来获取 关联的 <ShopController>
    3.4 使用的时候,用controller来获取ShopController对应的数据与方法
    3.5 用obx来实现局部刷新

import 'package:demoapp/Demo/Get/Controller/ShopController.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';class  GetShoppageDemo extends GetView<ShopController> {const GetShoppageDemo({super.key});Widget build(BuildContext context) {print(Get.arguments);return Scaffold(appBar: AppBar(title: Text("GetView的使用"),),body: Obx((){return ListView(children: controller.dataList.map((value){return ListTile(title: Text(value),);}).toList(),);}),floatingActionButton: FloatingActionButton(onPressed: (){controller.getDataRequest();},child: Icon(Icons.add),),);}
}
  1. 配置路由:
    4.1 用binding字段将ShopBindings()关联上,这样就不需要在第3步的时候,单独写Get.put()方法,让代码更优雅一点。
// getShopPageName 这个是自己定义的字符串
GetPage(name: getShopPageName, page: ()=> GetShoppageDemo(), binding: ShopBindings()),

4.4.4 效果图

在这里插入图片描述

5. GetX 自定义语言包 国际化配置

在我们使用系统自带 MaterialApp 来实现国际化配置,需要进行很多配置,而且还需要手动去依赖第三方组件,而使用 GetX 来实现国际化配置,你只需要一行代码即可实现切换,接下来看一下具体实现。

5.1 定义一个语言包

import 'package:get/get_navigation/src/root/internacionalization.dart';class Messages extends Translations {Map<String, Map<String, String>> get keys => {'zh_CN': {'hello': '你好 世界',},'de_DE': {'hello': 'Hallo Welt',}};
}

5.2 应用程序入口配置

  • translations: 国际化配置文件
  • locale: 设置默认语言,不设置的话为系统当前语言
  • fallbackLocale:添加一个回调语言选项,以备上面指定的语言翻译不存在
return GetMaterialApp(// 你的翻译 translations: Messages(), // 将会按照此处指定的语言翻译 locale: Locale('zh', 'CN'), // 添加一个回调语言选项,以备上面指定的语 言翻译不存在fallbackLocale: Locale('en', 'US'), 
);

5.3 调用语言包

只要将 .tr 追加到指定的键上,就会使用 Get.locale 和 Get.fallbackLocale 的当前值进行翻译。

Text('hello'.tr);

5.4 改变语言

调用 Get.updateLocale(locale) 来更新语言环境。然后翻译会自动使用新的locale。
更新后所有页面生效!

var locale = Locale('en', 'US'); 
Get.updateLocale(locale);

5.5 完整代码

import 'package:get/get.dart';class Messages extends Translations {Map<String, Map<String, String>> get keys => {'zh_CN': {'hello': '你好 世界',},'de_DE': {'hello': 'Hallo Welt',}};
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import './language/message.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return GetMaterialApp(title: 'Flutter Demo',translations: Messages(),locale: const Locale('zh', 'CN'),fallbackLocale: const Locale('en', 'US'),theme: ThemeData(primarySwatch: Colors.blue,),home: const MyHomePage(),);}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';class MyHomePage extends StatefulWidget {const MyHomePage({super.key});State<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Title'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('title'.tr),const SizedBox(),Text('hello'.tr),ElevatedButton(onPressed: () {var locale = const Locale('zh', 'CN');Get.updateLocale(locale);},child: const Text("切换到中文")),const SizedBox(height: 20,),ElevatedButton(onPressed: () {var locale = const Locale('en', 'US');Get.updateLocale(locale);},child: const Text("切换到英文")),],),),);}
}

相关文章:

Flutter_学习记录_状态管理之GetX

1. 状态管理、Flutter Getx介绍 1.1 状态管理 通俗的讲&#xff1a;当我们想在多个页面&#xff08;组件/Widget&#xff09;之间共享状态&#xff08;数据&#xff09;&#xff0c;或者一个页面&#xff08;组件/Widget&#xff09;中的多个子组件之间共享状态&#xff08;数…...

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_09自定义单元格的固定表头表格

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_09自定义单元格…...

基于 Prometheus + Grafana 监控微服务和数据库

以下是基于 Prometheus Grafana 监控微服务和数据库的详细指南&#xff0c;包含架构设计、安装配置及验证步骤&#xff1a; 一、整体架构设计 二、监控微服务 1. 微服务指标暴露 Spring Boot 应用&#xff1a; xml <!-- 添加 Micrometer 依赖 --> <dependency>…...

文件解析漏洞

一&#xff0c;IIS解析漏洞 1&#xff0c;IIS6.X 目录解析 在iis的⽹站根⽬录新建⼀个名为q.asp的⽂件&#xff0c;在q.asp中新建⼀个txt⽂件 在外部浏览器中访问windows2003的iis⽹站中的1.txt 发现asp代码被执⾏ 2&#xff0c;IIS6.X 畸形文件解析 在iis的⽹站根⽬录新建⼀…...

C++学习笔记(二十一)——文件读写

一、文件读写 作用&#xff1a; 文件读写指的是将数据从程序存储到文件&#xff0c;或从文件读取数据&#xff0c;以实现数据的持久化存储。 C 提供了 fstream 头文件&#xff0c;用于文件操作&#xff0c;主要包括&#xff1a; ofstream&#xff08;输出文件流&#xff09;—…...

Ubuntu上部署Flask+MySQL项目

一、服务器安装python环境 1、安装gcc&#xff08;Ubuntu默认已安装&#xff09; 2、安装python源码 wget https://www.python.org/ftp/python/3.13.2/Python-3.13.2.tar.xz 3、安装Python依赖库 4、配置python豆瓣源 二、服务器安装虚拟环境 1、安装virtualenv pip3.10 ins…...

Unity WebGL项目访问时自动全屏

Unity WebGL项目访问时自动全屏 打开TemplateData/style.css文件 在文件最下方添加红色框内的两行代码 使用vscode或者其他编辑器打开index.html 将按钮注释掉&#xff0c;并且更改为默认全屏...

C#RTSP代理推流程序

将不支持rtsp的相机通过rtspserver实现推流 主要功能 1. rtsp交互 2. udp推流 3. Bitmap转H264,RTP打包 4. 支持多路播放...

Redis--渐进式遍历

目录 一、引言 二、介绍 三、命令 四、总结 一、引言 本篇文章将介绍Redis中的渐进式遍历 二、介绍 一般使用keys * 来获取所有的key&#xff0c;但这样的操作如果数据量很大的时候&#xff0c;会将服务器给卡死&#xff0c;所以通过渐进式遍历&#xff0c;就会避免这个问题…...

PyTorch深度学习框架60天进阶学习计划 - 第23天:Transformer架构解析

让我继续完成机器翻译示例的代码&#xff1a; PyTorch深度学习框架60天进阶学习计划&#xff1a;第23天 Transformer架构解析 学习目标 推导自注意力机制数学公式详解位置编码的傅里叶基函数设计对比编码器-解码器结构的信息流动差异 1. Transformer架构概述 Transformer架…...

《C#上位机开发从门外到门内》3-4:基于TCP/IP的远程监控系统设计与实现

文章目录 一、项目概述二、系统架构设计三、通信协议设计四、功能模块实现五、系统安全性与稳定性六、性能优化与测试七、实际应用案例八、结论 随着信息技术的飞速发展&#xff0c;远程监控系统在工业自动化、智能家居、环境监测等领域的应用日益广泛。基于TCP/IP协议的远程监…...

【MySQL】MySQL审计工具Audit Plugin安装使用

MySQL审计工具Audit Plugin安装使用 https://www.cnblogs.com/waynechou/p/mysql_audit.html MySQL 5.6 开启审计功能 https://blog.51cto.com/u_15127556/4344503 MySQL之添加日志审计功能 https://blog.csdn.net/weixin_43279032/article/details/105507170 MySQL开启日志记录…...

Flutter 按钮组件 ElevatedButton 详解

目录 1. 引言 2. ElevatedButton 的基本用法 3. 主要属性 4. 自定义按钮样式 4.1 修改背景颜色和文本颜色 4.2 修改按钮形状和边框 4.3 修改按钮大小 4.4 阴影控制 4.5 水波纹效果 5. 结论 相关推荐 1. 引言 在 Flutter 中&#xff0c;ElevatedButton 是一个常用的…...

AndroidStudio+Android8.0下的Launcher3 导入,编译,烧录,调试

文章目录 编译完成搜索输出文件Android.mk配置gradle编译环境报错一报错二报错三输出文件下载INSTALL_FAILED_TEST_ONLY查找系统签名查找签名工具开始签名查看签名签名问题重新生成秘钥解决方案生成成功挽救错误:重新刷机更换testkey秘钥keystore生成keystoreINSTALL_FAILED_S…...

【差分约束】P5590 赛车游戏|省选-

本文涉及知识点 【数学 线性代数】差分约束 P5590 赛车游戏 题目描述 R 君和小伙伴打算一起玩赛车。但他们被老司机 mocania 骗去了秋名山。 秋名山上有 n n n 个点和 m m m 条边&#xff0c;R 君和他的小伙伴要从点 1 1 1 出发开往点 n n n&#xff0c;每条边都有一个…...

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包&#xff08;内有教程&#xff09; 刷机教程简单说明&#xff1a; 1、把下载好的刷机包&#xff0c;U盘里建立一个upgrade文件夹&#xff0c;固件放入此文件夹里&#xff0c;放入U盘中&#xff0c;注意升级包为压缩包不要对…...

【软件工程】06_软件设计

6.1 软件设计概述 1. 软件设计的目标 软件设计的最基本目标就是回答 “概括地描述系统如何实现用户所提出来的功能和性能等方面的需求?” 这个问题。 软件设计的目标是根据软件需求分析的结果,设想并设计软件,即根据目标系统的逻辑模型确定目标系统的物理模型。包括软件体系…...

在Flutter中使用Future读取一个大文件会导致线程阻塞吗

目录 一、Future 与文件读取的机制 1. Dart 的异步 I/O 原理 2. 代码示例 二、什么情况下会阻塞主线程? 1. I/O 操作本身不会阻塞 2. 数据处理可能阻塞 3. 示例对比 三、如何避免阻塞主线程? 1. 将耗时操作移到 Isolate 2. 使用 compute 函数(简化 Isolate 操作)…...

2025-03-17 Unity 网络基础1——网络基本概念

文章目录 1 网络1.1 局域网1.2 以太网1.3 城域网1.4 广域网1.5 互联网&#xff08;因特网&#xff09;1.6 万维网1.7 小结 2 IP 地址2.1 IP 地址2.2 端口号2.3 Mac 地址2.4 小结 3 客户端与服务端3.1 客户端3.2 服务端3.3 网络游戏中的客户端与服务端 1 网络 ​ 在没有网络之前…...

2025-03-17 学习记录--C/C++-PTA 习题4-8 高空坠球

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 习题4-8 高空坠球 皮球从某给定高度自由落下&#xff0c;触地后反弹到原高度的一半&#xff0c;再落下&…...

Java网络编程socket

一、UDP 特点&#xff1a; ① 用户数据报协议&#xff08;User Datagram Protocol&#xff09; ​ ② UDP是面向无连接通信协议 ​③ 速度快&#xff0c;一次只能传输64KB数据&#xff0c;数据不安全&#xff0c;容易丢失 &#xff08;1&#xff09;单播 一对一 客户端&#xf…...

蓝桥杯备赛 Day0_移动零

&#x1f388; 个人主页&#x1f449;&#xff1a;tbRNA-CSDN博客tbRNA-CSDN博客tbRNA-CSDN博客 &#x1f4af; 个人简介&#xff1a;在校大学生一枚&#x1f48b;. &#x1f60d; 希望我的文章对大家有着不一样的帮助&#xff0c;欢迎大家关注我&#xff0c;感谢大家的多多支持…...

Razor C# 变量

Razor C# 变量 引言 在ASP.NET MVC和Razor视图引擎中,变量是构建动态网页的基础。理解Razor C#变量的使用对于开发者来说至关重要。本文将详细介绍Razor C#变量的概念、类型、作用域以及如何在实际项目中有效使用它们。 一、Razor C# 变量的概念 Razor C# 变量是存储在Raz…...

产品更新丨谷云科技ETLCloud 3月更新速递

本月&#xff0c;我们的数据集成产品ETLCloud继续迎来多项更新&#xff0c;进一步提升系统的兼容性和用户体验。以下是本月更新的亮点内容&#xff1a; 新增10项功能组件&#xff0c;持续丰富产品易用性 聚水潭-奇门通用组件 新增聚水潭-奇门通用组件&#xff0c;帮助企业更…...

如何高效定位网络丢包问题?

引言 本期分享一个比较常见的网络问题--丢包。例如我们去ping一个网站&#xff0c;如果能ping通&#xff0c;且网站返回信息全面&#xff0c;则说明与网站服务器的通信是畅通的&#xff0c;如果ping不通&#xff0c;或者网站返回的信息不全等&#xff0c;则很可能是数据被丢包…...

gitlab将本地项目提交到远程dev分支

获取Git路径 首先从远程获取到git路径&#xff0c;将给的git地址进行克隆到本地文件&#xff1b; git clone http:************.git 按照git地址的文件路径将本地项目&#xff0c;拷贝到目标文件中 在该路径中&#xff0c;初始化命令&#xff1b; # 初始化项目 git init #…...

Linux命令学习使用列表

Linux命令学习使用列表 1 系统启动相关2 系统网络相关3 系统磁盘相关4 系统定时任务5 系统进程监控 1 系统启动相关 1.1 麒麟V10 sp3修改选择默认启动项 2 系统网络相关 2.1 Linux IP 配置  2.2 ping监测网络通信情况 3 系统磁盘相关 4 系统定时任务 5 系统进程监控 5.1 L…...

分布式锁: 并发时,redis如何避免删别人的锁

在使用Redis实现分布式锁的时候&#xff0c;如何避免在并发情况下误删别人的锁。首先&#xff0c;分布式锁的基本概念&#xff1a;是多个客户端在访问共享资源时&#xff0c;通过某种机制来确保同一时间只有一个客户端能持有锁。 Redis通常用SET命令加上NX选项来创建锁&#xf…...

解决 Jupyter Notebook 中本地模块修改不生效的问题

解决 Jupyter Notebook 中本地模块修改不生效的问题 问题原因 当你在 Jupyter Notebook 中导入本地目录的库&#xff0c;修改后重新运行 import 语句却发现修改没有生效&#xff0c;这是因为 Python 的模块缓存机制。Python 解释器会将已导入的模块缓存在 sys.modules 字典中…...

蓝桥杯嵌入式赛道复习笔记2(按键控制LED灯,双击按键,单击按键,长按按键)

硬件原理解释 这张图展示了一个简单的按键电路原理图&#xff0c;其中包含四个按键&#xff08;PB0、PB1、PB2、PB3、PA0&#xff09;&#xff0c;每个按键通过一个10kΩ的上拉电阻连接到VDD&#xff08;电源电压&#xff09;&#xff0c;并接地&#xff08;GND&#xff09;。 …...

简单爬虫--框架

简单爬虫 import requests import re import chardet# 模拟浏览器的请求头 headers {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" }# 发送 HTTP 请求获取百…...

游戏引擎学习第163天

我们可以在资源处理器中使用库 因为我们的资源处理器并不是游戏的一部分&#xff0c;所以它可以使用库。我说过我不介意让它使用库&#xff0c;而我提到这个的原因是&#xff0c;今天我们确实有一个选择——可以使用库。 生成字体位图的两种方式&#xff1a;求助于 Windows 或…...

多模态模型Orpheus,基于病理图像的乳腺癌复发风险智能评估工具|顶刊解读·25-03-17

小罗碎碎念 在医学领域&#xff0c;尤其是乳腺癌治疗方面&#xff0c;准确评估患者的复发风险至关重要。对于占乳腺癌很大比例的 HR/HER2 - 亚型患者&#xff0c;目前主要依靠 Oncotype DX 的复发评分&#xff08;RS&#xff09;来指导治疗决策。 然而&#xff0c;该检测存在…...

基于MapReduce的气候数据分析

标题:基于MapReduce的气候数据分析 内容:1.摘要 本文聚焦于基于MapReduce的气候数据分析。背景在于随着全球气候变化问题日益严峻&#xff0c;海量气候数据的高效处理和分析成为关键。目的是利用MapReduce技术对气候数据进行有效挖掘&#xff0c;以揭示气候变化规律和趋势。方…...

Spring 原生启动过程

Spring&#xff08;Spring Framework&#xff09;的原生启动过程&#xff0c;它主要涉及 ApplicationContext 的初始化、BeanFactory 的加载、Bean 的创建与依赖注入。下面详细解析&#xff1a; Spring 原生启动过程 Spring 本身不依赖 SpringApplication&#xff0c;其核心在…...

【React】useEffect、useLayoutEffect底层机制

目录 useEffect不设置依赖设置空数组&#xff0c;无依赖设置多个依赖返回值是一个函数总结useEffect的使用环境useEffect 中发送请求错误示例用.then获取数据在useEffect创建一个函数 总结 useLayoutEffectuseLayoutEffect 和useEffect区别执行时机&#xff1a;浏览器渲染的关系…...

RTSP/Onvif视频安防监控平台EasyNVR调用接口返回匿名用户名和密码的原因排查

视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入&#xff0c;并能对接入的视频流进行处理与多端分发&#xff0c;包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。平台拓展性强、支持二次开发与集成&#xff0c;可应用在景区、校园、水利、社区、工地等场…...

Linux-数据结构-线性表-单链表

一.链表的概念 【1】线性表的链式存储 解决顺序存储的缺点&#xff0c;插入和删除&#xff0c;动态存储问题。 【2】特点&#xff1a; 线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素&#xff0c;存储单元可以是连续的&#xff0c;也可以不连续。可以被存…...

基于SpringBoot+Vue3实现的宠物领养管理平台功能一

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会经济的发展和人们生活水平的提高&#xff0c;越来越多的人开始关注并参与到宠物领养中。宠物已经成为许多家庭的重要成员&#xff0c;人们对于宠物的关爱和照顾也日益增加。然而&#xff0c;传统的宠物领养流程存在诸多不便&a…...

DeepSeek进阶应用(二):结合Kimi制作PPT(双AI协作教程)

🌟引言: DeepSeek作为国产AI大模型,以强大的逻辑推理和结构化内容生成能力著称,擅长根据用户需求生成PPT大纲或Markdown文本;Kimi的PPT助手则能解析结构化内容并套用模板快速生成美观的PPT,两者结合实现“内容+设计”全流程自动化 名人说:苔花如米小,也学牡丹开。——…...

准确---快速安装nginx

1. 安装 Nginx 和 Stream 模块 首先&#xff0c;使用 yum 安装 Nginx 及其 Stream 模块&#xff1a; yum install nginx yum install nginx-mod-stream这将安装 Nginx 及其 Stream 模块&#xff0c;Stream 模块用于处理 TCP 和 UDP 流量&#xff0c;通常用于代理、负载均衡等…...

本地知识库RAG总结

目录 RAG流程: 知识库的要求&#xff1a; 知识抽取&#xff1a; 知识存储: 向量化: 知识检索: 应用客户端: RAG智能问答应用几个痛点&#xff1a; 如何提升召回率改进思路&#xff1a; 如何提升回答专业性&#xff1a; RAG评测&#xff1a; 总结&#xff1a; 参考…...

Trae IDE 介绍与使用教程

一、产品概述 Trae IDE 是由字节跳动推出的国内首个原生AI集成开发环境&#xff0c;专为中文开发者深度定制&#xff0c;旨在通过智能化工具降低编程门槛&#xff0c;提升开发效率。作为对标国外Cursor的国产替代方案&#xff0c;Trae不仅继承了AI驱动的代码生成与补全功能&am…...

OceanBase 用户问题精选答疑:OceanBase 版本升级解析

背景 此篇博客的源自于OceanBase社区论坛内一位名为皇甫侯的热心用户所提的建议&#xff0c;希望向OceanBase的用户介绍OceanBase的版本升级路径。本文以一个版本升级为示例&#xff0c;汇总了对用户而言比较重要的版本升级要点&#xff0c;期望通过这份分享&#xff0c;能让读…...

SpringBoot 和vue前后端配合开发网页拼图10关游戏源码技术分享

今天分享一个 前后端结合 的网页游戏 开发项目源码技术。 这也是我第一次写游戏类的程序&#xff0c;虽然不是特别复杂的游戏&#xff0c;但是是第一次写&#xff0c;肯定要记录一下了&#xff0c;哈哈。 游戏的内容 就是 我们显示中玩的那个 拼图碎片的 游戏&#xff0c;类似下…...

LeetCode 1005. K 次取反后最大化的数组和 java题解

https://leetcode.cn/problems/maximize-sum-of-array-after-k-negations/description/ 看着简单但是写si人的一题。 class Solution {public int largestSumAfterKNegations(int[] nums, int k) {Arrays.sort(nums);//排序int last_negative-1,first_positive-1;//最后一个负…...

c++ 类和对象 —— 中 【复习笔记】

1. 类的默认成员函数 如果一个类什么成员都没有&#xff0c;简称空类。但实际上&#xff0c;任何类在不写成员时&#xff0c;编译器会自动生成6个默认成员函数&#xff08;用户未显式实现&#xff0c;编译器生成的成员函数&#xff09; 这6个成员函数可分为三类&#xff1a; …...

「速通AI编程开发」共学(三):提示词(Prompts)配置项

「速通AI编程开发」共学&#xff08;三&#xff09; 一、共学课程来源学习初衷 二、介绍不同模式下的提示词&#xff08;Prompts&#xff09;支持性提示词 三、提示词学习材料分享 一、共学课程来源 Datawhale通过开源学习模式&#xff0c;助力AI学习者与知识连接&#xff0c;…...

Spring Cloud Stream - 构建高可靠消息驱动与事件溯源架构

一、引言 在分布式系统中&#xff0c;传统的 REST 调用模式往往导致耦合&#xff0c;难以满足高并发和异步解耦的需求。消息驱动架构&#xff08;EDA, Event-Driven Architecture&#xff09;通过异步通信、事件溯源等模式&#xff0c;提高了系统的扩展性与可观测性。 作为 S…...

电脑如何录屏

以下是电脑录屏的常用方法总结&#xff0c;涵盖系统自带工具、第三方软件及进阶功能&#xff0c;结合不同场景需求推荐最佳方案&#xff1a; 一、系统自带工具 Xbox Game Bar&#xff08;Windows 10/11&#xff09; 操作步骤&#xff1a;按 WinG 打开游戏栏 → 点击录制按钮&am…...