如何在Flutter Windows桌面应用中实现Dart与C++的Event Channel
Flutter Windows 实现Event Channel异步事件流示例
Windows原生端(flutter_windows.cpp)实现
以下是完整可运行代码,替换默认的flutter_windows.cpp内容即可:
#include "flutter_window.h" #include <flutter/event_channel.h> #include <flutter/event_stream_handler_functions.h> #include <flutter/method_channel.h> #include <flutter/standard_method_codec.h> #include <windows.h> #include <memory> #include <optional> #include <thread> // 自定义事件流处理器,负责持续发送数据 class CustomStreamHandler : public flutter::StreamHandler { public: CustomStreamHandler() {} ~CustomStreamHandler() override { // 停止事件发送线程 stop_thread_ = true; if (event_thread_.joinable()) { event_thread_.join(); } } private: std::thread event_thread_; bool stop_thread_ = false; std::unique_ptr<flutter::EventSink> event_sink_; // 监听事件触发时执行 flutter::StreamHandlerError OnListen( const flutter::EncodableValue* arguments, std::unique_ptr<flutter::EventSink> events) override { event_sink_ = std::move(events); stop_thread_ = false; // 启动独立线程持续发送数据 event_thread_ = std::thread([this]() { int counter = 0; while (!stop_thread_) { if (event_sink_) { // 每秒发送一次递增计数 event_sink_->Success(flutter::EncodableValue(counter++)); } Sleep(1000); } }); return flutter::StreamHandlerError(); } // 取消监听时执行 flutter::StreamHandlerError OnCancel( const flutter::EncodableValue* arguments) override { stop_thread_ = true; if (event_thread_.joinable()) { event_thread_.join(); } event_sink_.reset(); return flutter::StreamHandlerError(); } }; FlutterWindow::FlutterWindow(const flutter::DartProject& project) : project_(project) {} FlutterWindow::~FlutterWindow() {} bool FlutterWindow::OnCreate() { if (!Win32Window::OnCreate()) { return false; } RECT frame = GetClientArea(); // 初始化Flutter引擎 flutter_controller_ = std::make_unique<flutter::FlutterViewController>( frame.right - frame.left, frame.bottom - frame.top, project_); if (!flutter_controller_->engine() || !flutter_controller_->view()) { return false; } // 获取插件注册器,用于注册Event Channel auto registrar = flutter_controller_->engine()->GetPluginRegistrar(); // 注册Event Channel,通道名称需与Flutter端完全一致 auto event_channel = std::make_unique<flutter::EventChannel>(registrar->messenger(), "com.example/event_stream", &flutter::StandardMethodCodec::GetInstance()); auto stream_handler = std::make_unique<CustomStreamHandler>(); event_channel->SetStreamHandler(std::move(stream_handler)); // 保留原有Method Channel代码(如果存在) // ... SetChildContent(flutter_controller_->view()->GetNativeWindow()); flutter_controller_->engine()->SetNextFrameCallback([&]() { this->Show(); }); return true; } void FlutterWindow::OnDestroy() { if (flutter_controller_) { flutter_controller_ = nullptr; } Win32Window::OnDestroy(); } LRESULT FlutterWindow::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept { if (flutter_controller_) { std::optional<LRESULT> result = flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, lparam); if (result) { return *result; } } switch (message) { case WM_FONTCHANGE: flutter_controller_->engine()->ReloadSystemFonts(); break; } return Win32Window::MessageHandler(hwnd, message, wparam, lparam); }
Flutter Dart端对应实现
在Flutter项目主文件中添加事件监听代码:
import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final EventChannel _eventChannel = const EventChannel('com.example/event_stream'); StreamSubscription? _subscription; int _receivedCounter = 0; @override void initState() { super.initState(); _startListening(); } void _startListening() { _subscription = _eventChannel.receiveBroadcastStream().listen( (data) { setState(() { _receivedCounter = data as int; }); }, onError: (error) => print('监听错误:$error'), onDone: () => print('事件流已终止'), ); } @override void dispose() { _subscription?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Event Channel 演示')), body: Center( child: Text('Windows端发送计数:$_receivedCounter'), ), ), ); } }
关键注意事项
- 通道名称一致性:Windows端与Flutter端的Event Channel名称必须完全匹配
- 线程安全:Windows端通过独立线程发送数据,避免阻塞UI线程
- 资源清理:窗口销毁或取消监听时,必须停止线程并释放资源,防止内存泄漏
- 错误处理:可在
OnListen/OnCancel中返回StreamHandlerError,将错误信息传递给Flutter端
内容的提问来源于stack exchange,提问作者Harish Kandekar
相关产品推荐
相关产品推荐

