news 2026/4/3 1:10:42

Flutter for OpenHarmony 实战:独木桥问题完整开发指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter for OpenHarmony 实战:独木桥问题完整开发指南

Flutter for OpenHarmony 实战:独木桥问题模拟系统完整开发指南

文章目录

  • Flutter for OpenHarmony 实战:独木桥问题模拟系统完整开发指南
    • 摘要
    • 一、项目背景与功能概述
      • 1.1 独木桥问题背景
      • 1.2 应用功能规划
      • 1.3 人物参数设计
    • 二、独木桥问题规则
      • 2.1 桥的约束条件
      • 2.2 过桥流程
      • 2.3 人物分布
    • 三、技术选型与架构设计
      • 3.1 核心技术栈
      • 3.2 应用架构
      • 3.3 数据流设计
    • 四、数据模型设计
      • 4.1 人物类定义
      • 4.2 桥状态枚举
      • 4.3 人物初始化
    • 五、UI界面实现
      • 5.1 控制面板
      • 5.2 桥状态显示
      • 5.3 人员卡片
    • 六、异步队列处理
      • 6.1 开始模拟
      • 6.2 队列处理核心
      • 6.3 过桥模拟
      • 6.4 重置模拟
    • 七、完整代码实现
      • 7.1 应用入口
      • 7.2 状态管理
      • 7.3 AppBar设计
    • 八、运行效果与测试
      • 8.1 项目运行命令
      • 8.2 功能测试清单
    • 九、总结

摘要

独木桥问题是经典的并发同步问题,展示了资源互斥访问的场景。本文将详细介绍如何使用Flutter for OpenHarmony框架开发一款独木桥问题模拟系统。文章涵盖了人物数据模型、桥状态管理、异步队列处理、Future延迟模拟等核心技术点。通过本文学习,读者将掌握Flutter在鸿蒙平台上的异步编程技巧,了解并发模拟与资源管理的实现方法。


一、项目背景与功能概述

1.1 独木桥问题背景

独木桥问题是操作系统中的经典同步问题:

  • 南侧和北侧各有若干人要过桥
  • 桥一次只能容纳一个人
  • 需要保证所有人安全过桥
  • 展示了互斥锁和队列管理的概念

1.2 应用功能规划

功能模块具体功能
人物管理南侧9人、北侧8人,不同过桥速度
桥状态显示显示桥空闲/被占用状态
队列处理按顺序依次过桥
过程模拟异步模拟每个人过桥过程
进度统计显示已过桥人数
控制功能开始/重置模拟

1.3 人物参数设计

参数说明示例
id唯一标识S1, S2…N1, N2…
name显示名称南1, 南2…北1, 北2…
side所属方向south, north
crossingSpeed过桥速度(毫秒)1000-2800

二、独木桥问题规则

2.1 桥的约束条件

桥是一个共享资源,具有以下约束:

  • 桥一次只能容纳一个人
  • 同一时刻只能有一人过桥
  • 其他人必须等待桥空闲

2.2 过桥流程

2.3 人物分布

方向人数标识
南侧9人S1-S9
北侧8人N1-N8
总计17人-

三、技术选型与架构设计

3.1 核心技术栈

UI组件

  • ListView:显示人员列表
  • Card:人员卡片展示
  • SnackBar:完成提示

状态管理

  • StatefulWidget管理模拟状态
  • setState更新UI

异步处理

  • Future.delayed:模拟过桥时间
  • async/await:异步队列处理

3.2 应用架构

BridgeCrossingApp (应用根组件) └── BridgeCrossingPage (模拟页面) ├── AppBar (导航栏 + 进度显示) ├── 控制面板 │ ├── 开始按钮 │ └── 重置按钮 ├── 桥状态显示 │ ├── 空闲状态 │ └── 占用状态 └── 人员列表 └── PersonCard (17个)

3.3 数据流设计


四、数据模型设计

4.1 人物类定义

classPerson{finalStringid;// 唯一标识finalStringname;// 显示名称finalStringside;// 'south' 或 'north'bool isOnBridge;// 是否在桥上bool hasCrossed;// 是否已过桥int crossingSpeed;// 过桥速度(毫秒)Person({requiredthis.id,requiredthis.name,requiredthis.side,this.isOnBridge=false,this.hasCrossed=false,this.crossingSpeed=1000,});Colorgetcolor=>side=='south'?Colors.blue:Colors.orange;}

4.2 桥状态枚举

enumBridgeStatus{idle,// 空闲occupied,// 被占用}

4.3 人物初始化

void_initializePeople(){_people.clear();// 南侧9人for(int i=1;i<=9;i++){_people.add(Person(id:'S$i',name:'南$i',side:'south',crossingSpeed:1000+(i*200),// 不同速度));}// 北侧8人for(int i=1;i<=8;i++){_people.add(Person(id:'N$i',name:'北$i',side:'north',crossingSpeed:1000+(i*150),// 不同速度));}setState((){_crossedCount=0;_hasStarted=false;});}

五、UI界面实现

5.1 控制面板

Container(padding:constEdgeInsets.all(16),color:Colors.teal.shade50,child:Row(children:[ElevatedButton.icon(onPressed:_hasStarted?null:_startSimulation,icon:constIcon(Icons.play_arrow),label:constText('开始模拟'),style:ElevatedButton.styleFrom(backgroundColor:Colors.green,foregroundColor:Colors.white,),),constSizedBox(width:12),ElevatedButton.icon(onPressed:_resetSimulation,icon:constIcon(Icons.refresh),label:constText('重置'),style:ElevatedButton.styleFrom(backgroundColor:Colors.grey,),),],),)

5.2 桥状态显示

Container(padding:constEdgeInsets.all(16),color:Colors.grey.shade100,child:Row(mainAxisAlignment:MainAxisAlignment.center,children:[Icon(_bridgeStatus==BridgeStatus.occupied?Icons.block:Icons.check_circle,color:_bridgeStatus==BridgeStatus.occupied?Colors.red:Colors.green,),constSizedBox(width:8),Text(_bridgeStatus==BridgeStatus.occupied?'桥被占用:${_currentCrosser?.name}正在过桥':'桥空闲',style:constTextStyle(fontSize:16,fontWeight:FontWeight.bold),),],),)

5.3 人员卡片

Widget_buildPersonCard(Personperson){StringstatusText;ColorstatusColor;if(person.isOnBridge){statusText='正在过桥...';statusColor=Colors.orange;}elseif(person.hasCrossed){statusText='已过桥 ✓';statusColor=Colors.green;}else{statusText='等待中';statusColor=Colors.grey;}returnCard(margin:constEdgeInsets.only(bottom:8),child:ListTile(leading:CircleAvatar(backgroundColor:person.color,child:Text(person.name.substring(1),style:constTextStyle(color:Colors.white,fontWeight:FontWeight.bold,),),),title:Text(person.name,style:constTextStyle(fontWeight:FontWeight.bold),),subtitle:Text('速度:${person.crossingSpeed}ms'),trailing:Container(padding:constEdgeInsets.symmetric(horizontal:12,vertical:6),decoration:BoxDecoration(color:statusColor,borderRadius:BorderRadius.circular(12),),child:Text(statusText,style:constTextStyle(color:Colors.white,fontWeight:FontWeight.bold,),),),),);}

六、异步队列处理

6.1 开始模拟

void_startSimulation(){if(_hasStarted)return;setState((){_hasStarted=true;});_processQueue();}

6.2 队列处理核心

void_processQueue()async{// 按顺序过桥for(varpersonin_people){if(!person.hasCrossed){await_crossBridge(person);setState((){_crossedCount++;});// 滚动到底部if(_scrollController.hasClients){_scrollController.animateTo(_scrollController.position.maxScrollExtent,duration:constDuration(milliseconds:300),curve:Curves.easeInOut,);}}}// 全部完成if(mounted){setState((){_bridgeStatus=BridgeStatus.idle;});ScaffoldMessenger.of(context).showSnackBar(constSnackBar(content:Text('所有人都已安全过桥!'),backgroundColor:Colors.green,),);}}

算法要点

  • 使用async/await实现异步顺序处理
  • await确保每个人完成后才开始下一个
  • mounted检查避免内存泄漏
  • 自动滚动跟踪当前过桥人

6.3 过桥模拟

Future<void>_crossBridge(Personperson)async{setState((){_bridgeStatus=BridgeStatus.occupied;_currentCrosser=person;person.isOnBridge=true;});// 模拟过桥时间awaitFuture.delayed(Duration(milliseconds:person.crossingSpeed));if(mounted){setState((){person.isOnBridge=false;person.hasCrossed=true;_bridgeStatus=BridgeStatus.idle;_currentCrosser=null;});}}

异步处理要点

  • Future.delayed模拟时间消耗
  • 多次setState更新不同状态
  • mounted检查确保组件存在

6.4 重置模拟

void_resetSimulation(){setState((){_hasStarted=false;_bridgeStatus=BridgeStatus.idle;_currentCrosser=null;_crossedCount=0;for(varpersonin_people){person.isOnBridge=false;person.hasCrossed=false;}});_initializePeople();}

七、完整代码实现

7.1 应用入口

voidmain(){runApp(constBridgeCrossingApp());}classBridgeCrossingAppextendsStatelessWidget{constBridgeCrossingApp({super.key});@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:'独木桥问题',theme:ThemeData(colorScheme:ColorScheme.fromSeed(seedColor:Colors.teal),useMaterial3:true,),home:constBridgeCrossingPage(),);}}

7.2 状态管理

class_BridgeCrossingPageStateextendsState<BridgeCrossingPage>{finalList<Person>_people=[];BridgeStatus_bridgeStatus=BridgeStatus.idle;Person?_currentCrosser;int _crossedCount=0;finalScrollController_scrollController=ScrollController();bool _hasStarted=false;@overridevoidinitState(){super.initState();_initializePeople();}@overridevoiddispose(){_scrollController.dispose();super.dispose();}}

7.3 AppBar设计

AppBar(title:constText('独木桥问题'),backgroundColor:Theme.of(context).colorScheme.inversePrimary,actions:[Center(child:Padding(padding:constEdgeInsets.only(right:16),child:Text('已过桥:$_crossedCount/17',style:constTextStyle(fontSize:16,fontWeight:FontWeight.bold),),),),],)

八、运行效果与测试

8.1 项目运行命令

cdE:\HarmonyOS\oh.code\bridge_crossing flutter run -d ohos

8.2 功能测试清单

初始化测试

  • 南侧显示9人(蓝色)
  • 北侧显示8人(橙色)
  • 所有人状态为"等待中"

模拟流程测试

  • 点击"开始模拟"后按钮禁用
  • 第一人上桥,状态变为"正在过桥"
  • 桥状态显示"被占用"
  • 过桥完成后状态变为"已过桥"
  • 自动开始下一人

状态显示测试

  • 桥状态实时更新
  • 当前过桥人正确显示
  • 已过桥计数准确

重置功能测试

  • 点击"重置"恢复初始状态
  • 所有进度清零
  • 可重新开始模拟

完成提示测试

  • 17人全部过桥后显示提示
  • 提示内容:“所有人都已安全过桥!”

九、总结

本文详细介绍了使用Flutter for OpenHarmony开发独木桥问题模拟系统的完整过程,涵盖了以下核心技术点:

  1. 数据模型:Person类、桥状态枚举、多属性管理
  2. 状态管理:桥状态、人物状态、进度统计
  3. 异步编程:Future.delayed、async/await、队列处理
  4. UI设计:ListView、Card、状态指示器
  5. 用户交互:开始/重置控制、自动滚动
  6. 资源管理:ScrollController生命周期

这个项目展示了Flutter在并发模拟和异步编程方面的完整流程。读者可以基于此项目添加更多功能,如:

  • 双向过桥(南北对开)
  • 优先级队列
  • 并行模拟多座桥
  • 性能统计与分析

通过本文的学习,读者应该能够理解异步编程的基本概念,掌握Flutter在鸿蒙平台上的异步处理技巧,为开发更复杂的并发应用打下基础。


欢迎加入开源鸿蒙跨平台社区: 开源鸿蒙跨平台开发者社区

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/30 23:41:03

简单理解:门电路

门电路的核心是用 ** 晶体管&#xff08;主要是 MOSFET&#xff09;** 作为开关元件&#xff0c;通过组合不同的晶体管连接方式&#xff0c;实现 “与、或、非” 等基本逻辑功能。下面从最基础的原理到具体电路&#xff0c;一步步拆解门电路的构成。 一、核心原理&#xff1a;…

作者头像 李华
网站建设 2026/3/26 6:10:04

Qwen3-ASR-0.6B实战:如何用Gradio搭建语音识别Web界面

Qwen3-ASR-0.6B实战&#xff1a;如何用Gradio搭建语音识别Web界面 1. 为什么选Qwen3-ASR-0.6B做语音识别&#xff1f; 你有没有遇到过这样的场景&#xff1a;开会录音要转文字、采访素材要整理成稿、外语视频想快速看懂内容&#xff0c;但手头没有好用的语音识别工具&#xf…

作者头像 李华
网站建设 2026/3/28 10:49:35

小白也能轻松玩转:yz-女生-角色扮演模型的5个实用技巧

小白也能轻松玩转&#xff1a;yz-女生-角色扮演模型的5个实用技巧 你是不是也试过打开一个AI绘图工具&#xff0c;输入“可爱少女、樱花背景、日系插画”&#xff0c;结果生成的图片不是脸歪了&#xff0c;就是手多了一只&#xff0c;再或者背景糊成一团&#xff1f;别急——这…

作者头像 李华
网站建设 2026/3/25 9:48:35

RexUniNLU应用案例:电商评论情感分析一键搞定

RexUniNLU应用案例&#xff1a;电商评论情感分析一键搞定 1. 你还在为电商评论分析发愁吗&#xff1f;不用标注、不写代码、不调模型 你有没有遇到过这些情况&#xff1a; 每天上千条用户评论堆在后台&#xff0c;人工翻看耗时又容易漏掉关键反馈找外包公司做情感分析&#…

作者头像 李华
网站建设 2026/3/28 21:37:11

Qwen3-Reranker-0.6B实战教程:Python API调用+批量文档重排代码实例

Qwen3-Reranker-0.6B实战教程&#xff1a;Python API调用批量文档重排代码实例 1. 这个模型到底能帮你解决什么问题&#xff1f; 你有没有遇到过这样的情况&#xff1a; 在做RAG应用时&#xff0c;检索模块返回了10个文档&#xff0c;但真正有用的可能只有第3个和第7个&#…

作者头像 李华
网站建设 2026/3/31 15:08:47

QWEN-AUDIO实战:用情感指令打造有温度的AI语音助手

QWEN-AUDIO实战&#xff1a;用情感指令打造有温度的AI语音助手 你有没有试过&#xff0c;对着一个语音助手说“我今天特别累”&#xff0c;它却用毫无波澜的语调回你一句“好的&#xff0c;已为您记录”&#xff1f; 不是它听不懂&#xff0c;而是它还没学会“共情”。 QWEN-A…

作者头像 李华