Flutter Linux平台下如何从原生C++代码调用Dart函数?
在Linux平台Flutter应用中实现C++调用Dart函数
Dart端配置
在Dart层,通过MethodChannel注册方法处理器,接收原生C++端发起的调用:
import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; class NativeBridge { static const MethodChannel _channel = MethodChannel('com.example/native_channel'); static void setupNativeCallback() { // 注册方法处理器,响应原生调用 _channel.setMethodCallHandler((call) async { switch (call.method) { case 'triggerDartFunction': // 解析原生传入的数据 final data = call.arguments as Map<String, dynamic>; print('收到原生数据: ${data['message']}'); // 执行业务逻辑函数 _handleNativeEvent(data); return 'Dart函数执行完成'; // 可选:返回结果给原生 default: throw MissingPluginException(); } }); } static void _handleNativeEvent(Map<String, dynamic> data) { // 这里写你的业务逻辑 print('处理原生事件ID: ${data['eventId']}'); } } void main() { WidgetsFlutterBinding.ensureInitialized(); NativeBridge.setupNativeCallback(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('C++调用Dart测试')), body: const Center(child: Text('等待原生事件...')), ), ); } }
C++端实现
在Linux原生代码(如main.cc或自定义插件文件)中,获取MethodChannel实例并触发Dart函数调用:
1. 初始化MethodChannel
在Flutter引擎初始化完成后创建通道实例:
#include <flutter/method_channel.h> #include <flutter/standard_method_codec.h> #include <flutter/flutter_engine.h> #include <map> #include <string> // 全局保存通道实例 std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> native_channel; void InitializeNativeChannel(flutter::FlutterEngine* engine) { auto channel = std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>( engine->messenger(), "com.example/native_channel", &flutter::StandardMethodCodec::GetInstance()); native_channel = std::move(channel); }
2. 触发Dart函数调用
当原生事件触发时,调用InvokeMethod向Dart发送数据:
// 示例:原生事件触发函数 void TriggerNativeEvent() { // 构造传递给Dart的参数 flutter::EncodableMap arguments; arguments[flutter::EncodableValue("message")] = flutter::EncodableValue("来自C++的事件通知"); arguments[flutter::EncodableValue("eventId")] = flutter::EncodableValue(1001); if (native_channel) { native_channel->InvokeMethod( "triggerDartFunction", std::make_unique<flutter::EncodableValue>(arguments), // 可选:处理Dart返回的结果 [](const flutter::MethodResult<flutter::EncodableValue>& result) { if (result.IsSuccess()) { const auto* value = result.SuccessValue(); if (value->IsString()) { std::string dart_result = std::get<std::string>(*value); printf("Dart返回结果: %s\n", dart_result.c_str()); } } else if (result.IsError()) { printf("调用失败: %s\n", result.ErrorMessage().c_str()); } }); } }
3. 线程安全处理
如果原生事件在非Flutter线程触发,需切换到Flutter任务线程执行调用:
// 切换到Flutter线程执行任务 void RunOnFlutterThread(flutter::FlutterEngine* engine, std::function<void()> task) { engine->task_runner()->PostTask(std::move(task)); } // 后台线程触发事件的示例 void BackgroundThreadEvent(flutter::FlutterEngine* engine) { RunOnFlutterThread(engine, []() { TriggerNativeEvent(); }); }
测试验证
- 确保Dart和C++端的通道名称完全一致(如
com.example/native_channel) - 在原生代码中触发
TriggerNativeEvent(比如通过定时器、按钮点击或业务逻辑条件) - 查看Dart控制台输出,确认数据接收和函数执行情况
常见问题
- 通道名称不匹配:两端通道字符串必须完全相同,否则无法建立通信
- 参数类型不兼容:使用
EncodableMap/EncodableValue处理复杂类型,确保两端解析逻辑一致 - 线程错误:必须在Flutter线程调用
InvokeMethod,否则会导致崩溃或无响应 - 通道实例为空:确保
InitializeNativeChannel在Flutter引擎初始化完成后调用
内容的提问来源于stack exchange,提问作者Khaled57
相关产品推荐
相关产品推荐

