You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:23:34