Flutter for OpenHarmony 实战:独木桥问题模拟系统完整开发指南
文章目录
- [Flutter for OpenHarmony 实战:独木桥问题模拟系统完整开发指南](#Flutter for OpenHarmony 实战:独木桥问题模拟系统完整开发指南)
-
- 摘要
- 一、项目背景与功能概述
-
- [1.1 独木桥问题背景](#1.1 独木桥问题背景)
- [1.2 应用功能规划](#1.2 应用功能规划)
- [1.3 人物参数设计](#1.3 人物参数设计)
- 二、独木桥问题规则
-
- [2.1 桥的约束条件](#2.1 桥的约束条件)
- [2.2 过桥流程](#2.2 过桥流程)
- [2.3 人物分布](#2.3 人物分布)
- 三、技术选型与架构设计
-
- [3.1 核心技术栈](#3.1 核心技术栈)
- [3.2 应用架构](#3.2 应用架构)
- [3.3 数据流设计](#3.3 数据流设计)
- 四、数据模型设计
-
- [4.1 人物类定义](#4.1 人物类定义)
- [4.2 桥状态枚举](#4.2 桥状态枚举)
- [4.3 人物初始化](#4.3 人物初始化)
- 五、UI界面实现
-
- [5.1 控制面板](#5.1 控制面板)
- [5.2 桥状态显示](#5.2 桥状态显示)
- [5.3 人员卡片](#5.3 人员卡片)
- 六、异步队列处理
-
- [6.1 开始模拟](#6.1 开始模拟)
- [6.2 队列处理核心](#6.2 队列处理核心)
- [6.3 过桥模拟](#6.3 过桥模拟)
- [6.4 重置模拟](#6.4 重置模拟)
- 七、完整代码实现
-
- [7.1 应用入口](#7.1 应用入口)
- [7.2 状态管理](#7.2 状态管理)
- [7.3 AppBar设计](#7.3 AppBar设计)
- 八、运行效果与测试
-
- [8.1 项目运行命令](#8.1 项目运行命令)
- [8.2 功能测试清单](#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 人物类定义
dart
class Person {
final String id; // 唯一标识
final String name; // 显示名称
final String side; // 'south' 或 'north'
bool isOnBridge; // 是否在桥上
bool hasCrossed; // 是否已过桥
int crossingSpeed; // 过桥速度(毫秒)
Person({
required this.id,
required this.name,
required this.side,
this.isOnBridge = false,
this.hasCrossed = false,
this.crossingSpeed = 1000,
});
Color get color => side == 'south' ? Colors.blue : Colors.orange;
}
4.2 桥状态枚举
dart
enum BridgeStatus {
idle, // 空闲
occupied, // 被占用
}
4.3 人物初始化
dart
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 控制面板

dart
Container(
padding: const EdgeInsets.all(16),
color: Colors.teal.shade50,
child: Row(
children: [
ElevatedButton.icon(
onPressed: _hasStarted ? null : _startSimulation,
icon: const Icon(Icons.play_arrow),
label: const Text('开始模拟'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
),
const SizedBox(width: 12),
ElevatedButton.icon(
onPressed: _resetSimulation,
icon: const Icon(Icons.refresh),
label: const Text('重置'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey,
),
),
],
),
)
5.2 桥状态显示

dart
Container(
padding: const EdgeInsets.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,
),
const SizedBox(width: 8),
Text(
_bridgeStatus == BridgeStatus.occupied
? '桥被占用:${_currentCrosser?.name}正在过桥'
: '桥空闲',
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
],
),
)
5.3 人员卡片

dart
Widget _buildPersonCard(Person person) {
String statusText;
Color statusColor;
if (person.isOnBridge) {
statusText = '正在过桥...';
statusColor = Colors.orange;
} else if (person.hasCrossed) {
statusText = '已过桥 ✓';
statusColor = Colors.green;
} else {
statusText = '等待中';
statusColor = Colors.grey;
}
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: CircleAvatar(
backgroundColor: person.color,
child: Text(
person.name.substring(1),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
title: Text(
person.name,
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text('速度: ${person.crossingSpeed}ms'),
trailing: Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: statusColor,
borderRadius: BorderRadius.circular(12),
),
child: Text(
statusText,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
六、异步队列处理
6.1 开始模拟
dart
void _startSimulation() {
if (_hasStarted) return;
setState(() {
_hasStarted = true;
});
_processQueue();
}
6.2 队列处理核心
dart
void _processQueue() async {
// 按顺序过桥
for (var person in _people) {
if (!person.hasCrossed) {
await _crossBridge(person);
setState(() {
_crossedCount++;
});
// 滚动到底部
if (_scrollController.hasClients) {
_scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
}
}
// 全部完成
if (mounted) {
setState(() {
_bridgeStatus = BridgeStatus.idle;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('所有人都已安全过桥!'),
backgroundColor: Colors.green,
),
);
}
}
算法要点
- 使用async/await实现异步顺序处理
- await确保每个人完成后才开始下一个
- mounted检查避免内存泄漏
- 自动滚动跟踪当前过桥人
6.3 过桥模拟
dart
Future<void> _crossBridge(Person person) async {
setState(() {
_bridgeStatus = BridgeStatus.occupied;
_currentCrosser = person;
person.isOnBridge = true;
});
// 模拟过桥时间
await Future.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 重置模拟
dart
void _resetSimulation() {
setState(() {
_hasStarted = false;
_bridgeStatus = BridgeStatus.idle;
_currentCrosser = null;
_crossedCount = 0;
for (var person in _people) {
person.isOnBridge = false;
person.hasCrossed = false;
}
});
_initializePeople();
}
七、完整代码实现
7.1 应用入口
dart
void main() {
runApp(const BridgeCrossingApp());
}
class BridgeCrossingApp extends StatelessWidget {
const BridgeCrossingApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '独木桥问题',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
useMaterial3: true,
),
home: const BridgeCrossingPage(),
);
}
}
7.2 状态管理
dart
class _BridgeCrossingPageState extends State<BridgeCrossingPage> {
final List<Person> _people = [];
BridgeStatus _bridgeStatus = BridgeStatus.idle;
Person? _currentCrosser;
int _crossedCount = 0;
final ScrollController _scrollController = ScrollController();
bool _hasStarted = false;
@override
void initState() {
super.initState();
_initializePeople();
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
}
7.3 AppBar设计
dart
AppBar(
title: const Text('独木桥问题'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
actions: [
Center(
child: Padding(
padding: const EdgeInsets.only(right: 16),
child: Text(
'已过桥: $_crossedCount/17',
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
),
],
)
八、运行效果与测试
8.1 项目运行命令
bash
cd E:\HarmonyOS\oh.code\bridge_crossing
flutter run -d ohos
8.2 功能测试清单
初始化测试
- 南侧显示9人(蓝色)
- 北侧显示8人(橙色)
- 所有人状态为"等待中"
模拟流程测试
- 点击"开始模拟"后按钮禁用
- 第一人上桥,状态变为"正在过桥"
- 桥状态显示"被占用"
- 过桥完成后状态变为"已过桥"
- 自动开始下一人
状态显示测试
- 桥状态实时更新
- 当前过桥人正确显示
- 已过桥计数准确
重置功能测试
- 点击"重置"恢复初始状态
- 所有进度清零
- 可重新开始模拟
完成提示测试
- 17人全部过桥后显示提示
- 提示内容:"所有人都已安全过桥!"
九、总结
本文详细介绍了使用Flutter for OpenHarmony开发独木桥问题模拟系统的完整过程,涵盖了以下核心技术点:
- 数据模型:Person类、桥状态枚举、多属性管理
- 状态管理:桥状态、人物状态、进度统计
- 异步编程:Future.delayed、async/await、队列处理
- UI设计:ListView、Card、状态指示器
- 用户交互:开始/重置控制、自动滚动
- 资源管理:ScrollController生命周期
这个项目展示了Flutter在并发模拟和异步编程方面的完整流程。读者可以基于此项目添加更多功能,如:
- 双向过桥(南北对开)
- 优先级队列
- 并行模拟多座桥
- 性能统计与分析
通过本文的学习,读者应该能够理解异步编程的基本概念,掌握Flutter在鸿蒙平台上的异步处理技巧,为开发更复杂的并发应用打下基础。
欢迎加入开源鸿蒙跨平台社区 : 开源鸿蒙跨平台开发者社区