Flutter框架跨平台鸿蒙开发——EventChannel事件通道

一、EventChannel概述

EventChannel用于从原生平台向Flutter发送连续的事件流,适合传感器、定位等实时数据。
持续事件
Stream
更新
HarmonyOS
EventChannel
Flutter监听
UI展示

|| 特性 | 说明 |

|------|------|

| 单向流 | 只支持原生向Flutter发送 |

| 持续数据 | 适合实时数据流 |

| 订阅模式 | 支持订阅和取消 |

| 事件驱动 | 数据到达自动推送 |

二、事件流机制

Flutter UI Stream EventChannel 原生平台 Flutter UI Stream EventChannel 原生平台 产生事件 转发事件 onData回调 setState更新 产生新事件 转发事件 onData回调

dart 复制代码
class _Page03EventChannel extends StatefulWidget {
  const _Page03EventChannel();

  @override
  State<_Page03EventChannel> createState() => _Page03EventChannelState();
}

class _Page03EventChannelState extends State<_Page03EventChannel> {
  static const eventChannel = EventChannel('com.example.demo/sensor');
  late StreamSubscription _subscription;
  List<double> _sensorData = [];
  bool _isListening = false;

  @override
  void initState() {
    super.initState();
  }

  void _startListening() {
    setState(() {
      _isListening = true;
      _sensorData = [];
    });

    // 模拟传感器数据流
    _subscription = Stream.periodic(const Duration(milliseconds: 200), (count) {
      return (DateTime.now().millisecond % 100) / 100.0;
    }).listen(
      (data) {
        setState(() {
          _sensorData.add(data);
          if (_sensorData.length > 50) {
            _sensorData.removeAt(0);
          }
        });
      },
      onError: (error) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('传感器错误: $error')),
        );
      },
    );
  }

  void _stopListening() {
    _subscription.cancel();
    setState(() {
      _isListening = false;
    });
  }

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.orange.shade50,
      padding: const EdgeInsets.all(20),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(20),
            decoration: BoxDecoration(
              color: Colors.orange.shade600,
              borderRadius: BorderRadius.circular(20),
            ),
            child: const Column(
              children: [
                Icon(Icons.sensors, size: 48, color: Colors.white),
                SizedBox(height: 16),
                Text(
                  'EventChannel',
                  style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold, color: Colors.white),
                ),
                SizedBox(height: 8),
                Text('事件通道流 - 页面 3/10', style: TextStyle(color: Colors.white70)),
              ],
            ),
          ),
          const SizedBox(height: 24),
          Expanded(
            child: Container(
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)),
              child: Column(
                children: [
                  // 模拟传感器波形
                  Expanded(
                    child: CustomPaint(
                      painter: _WavePainter(_sensorData),
                      child: Container(),
                    ),
                  ),
                  const SizedBox(height: 20),
                  Text(
                    '当前值: ${_sensorData.isNotEmpty ? _sensorData.last.toStringAsFixed(2) : '--'}',
                    style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: _isListening ? _stopListening : _startListening,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: _isListening ? Colors.red : Colors.orange.shade600,
                    ),
                    child: Text(
                      _isListening ? '停止监听' : '开始监听',
                      style: const TextStyle(color: Colors.white),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _WavePainter extends CustomPainter {
  final List<double> data;

  _WavePainter(this.data);

  @override
  void paint(Canvas canvas, Size size) {
    if (data.isEmpty) return;

    final paint = Paint()
      ..color = Colors.orange.shade600
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;

    final path = Path();
    final stepX = size.width / 50;
    final centerY = size.height / 2;

    for (int i = 0; i < data.length; i++) {
      final x = i * stepX;
      final y = centerY - (data[i] * centerY * 0.8);
      if (i == 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(_WavePainter oldDelegate) {
    return data != oldDelegate.data;
  }
}

三、监听管理

操作 方法 说明
订阅 listen() 开始监听事件
取消 cancel() 停止监听
错误处理 onError 处理异常
完成 onDone 流结束回调

四、应用场景

30% 25% 20% 15% 10% 典型应用场景 传感器数据 位置定位 网络状态 蓝牙连接 其他

五、最佳实践

  • ✅ 及时取消订阅
  • ✅ 限制数据更新频率
  • ✅ 处理错误和完成事件
  • ❌ 避免内存泄漏

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
李游Leo26 分钟前
HarmonyOS 7 + Spatial Recon Kit-C++:3DGS 高斯参数的非有限值隔离与可渲染性门禁【鸿蒙心迹】
开发语言·c++·3d·harmonyos
熊猫钓鱼>_>38 分钟前
Kotlin Multiplatform for OpenHarmony 实战:为 MVIKotlin 实现单向数据流适配
华为·ai编程·鸿蒙·openharmony·适配·数据流·mvkotlin
传奇开心果编程43 分钟前
【ArkUI进阶练中学】第12课:应用架构演进与遗留系统迁移
学习·ui·华为·harmonyos
传奇开心果编程3 小时前
【ArkUI进阶练中学】第13课:元服务与卡片开发
学习·ui·华为·harmonyos
李游Leo4 小时前
HarmonyOS 7 InsightBoard 多形态适配实录 06:ArkUI × 多设备回归:布局抖动、监听释放与全形态验收【鸿蒙心迹】
回归·kotlin·harmonyos
李游Leo4 小时前
HarmonyOS 7 PixelBridge 原生库适配实录 04:Native Buffer Pool、批任务背压与取消链路【鸿蒙心迹】
华为·harmonyos
李游Leo4 小时前
HarmonyOS 7 Spatial Recon Kit 开发实录 01:支持检测、Session 创建与首条有效重建链路【鸿蒙心迹】
华为·harmonyos
传奇开心果编程4 小时前
【ArkUI进阶练中学】第19课:AI安全与隐私治理
学习·ui·华为·harmonyos
李游Leo5 小时前
HarmonyOS 7 QuickDock 闪控窗开发实录 06:floatView × 回归验收:25轮场景回归、资源基线与发布前收口【鸿蒙心迹】
回归·kotlin·harmonyos