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

Flutter与Native双向消息传递及反向交互技术咨询

Flutter 与 Native 双向通信完全指南:从消息传递到反向调用

我来帮你理清楚Flutter和Native之间的双向通信问题——这在和硬件组件、特定Native API交互时特别常用,分两部分给你讲明白:


一、Flutter 向 Native 传递消息(单向调用)

最常用的方式是 Method Channel,本质是Flutter作为客户端调用Native端暴露的方法,步骤很清晰:

实现步骤

  1. Flutter端定义唯一的通道名称,创建MethodChannel实例;
  2. 调用invokeMethod传递方法名和参数;
  3. Native端注册相同通道名的MethodCallHandler,处理调用逻辑并返回结果。

代码示例

Flutter 端(Dart)

import 'package:flutter/services.dart';

class NativeMessenger {
  // 定义唯一通道名,建议用反向域名格式避免冲突
  static const _channel = MethodChannel('com.myapp/native_comm');

  // 封装发送消息的方法
  static Future<String> sendMessageToNative(String content) async {
    try {
      // 调用Native端的"receiveFlutterMessage"方法,携带参数
      final String result = await _channel.invokeMethod(
        'receiveFlutterMessage',
        {'message': content},
      );
      return result;
    } on PlatformException catch (e) {
      return "发送失败:${e.message}";
    }
  }
}

// 使用示例
// NativeMessenger.sendMessageToNative("Hello from Flutter!").then((res) => print(res));

Android 端(Kotlin)

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.myapp/native_comm"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        // 注册通道处理器
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when(call.method) {
                "receiveFlutterMessage" -> {
                    // 获取Flutter传递的参数
                    val message = call.argument<String>("message")
                    // 这里可以对接Native API或硬件组件
                    val response = "Native已收到:$message"
                    // 返回结果给Flutter
                    result.success(response)
                }
                else -> result.notImplemented() // 处理未定义的方法
            }
        }
    }
}

二、Native 主动向 Flutter 回传信息(反向通信)

这正是你关心的场景——Native需要主动通知Flutter(比如硬件状态变化、API回调结果),有两种核心方案:

2.1 用 Event Channels 处理持续事件流

适合需要持续推送数据的场景(比如传感器数据、网络状态监听),本质是Native向Flutter发送事件流。

代码示例

Flutter 端(Dart)
import 'package:flutter/services.dart';

class NativeEventReceiver {
  static const _eventChannel = EventChannel('com.myapp/native_events');

  // 暴露一个Stream供监听
  static Stream<String> get nativeEventStream {
    return _eventChannel.receiveBroadcastStream().map((event) => event.toString());
  }
}

// 使用示例
// NativeEventReceiver.nativeEventStream.listen((event) {
//   print("收到Native事件:$event");
// });
Android 端(Kotlin)
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel

class MainActivity : FlutterActivity() {
    private val EVENT_CHANNEL = "com.myapp/native_events"
    private var eventSink: EventChannel.EventSink? = null

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        // 注册事件流处理器
        EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL).setStreamHandler(
            object : EventChannel.StreamHandler {
                // Flutter开始监听时触发
                override fun onListen(arguments: Any?, sink: EventChannel.EventSink?) {
                    eventSink = sink
                    // 这里可以启动硬件监听,比如传感器回调
                    sendEventToFlutter("硬件已连接")
                }

                // Flutter停止监听时触发
                override fun onCancel(arguments: Any?) {
                    eventSink = null
                    // 停止硬件监听,释放资源
                }
            }
        )
    }

    // 主动向Flutter发送事件的方法
    private fun sendEventToFlutter(message: String) {
        eventSink?.success(message)
        // 出错时可以发送错误:eventSink?.error("ERROR_CODE", "错误信息", null)
        // 结束事件流:eventSink?.endOfStream()
    }
}

2.2 反向方法调用:Native 主动调用 Flutter 方法

适合单次主动调用(比如Native完成某个异步任务后通知Flutter),和Flutter调用Native的逻辑反过来——Native作为客户端调用Flutter暴露的方法。

代码示例

Flutter 端(Dart)
import 'package:flutter/services.dart';

class NativeCallHandler {
  static const _channel = MethodChannel('com.myapp/native_comm');

  // 初始化方法,注册Native调用的处理器
  static void setupNativeCallListener() {
    _channel.setMethodCallHandler((call) async {
      switch(call.method) {
        case "notifyFlutterTaskDone":
          val taskData = call.argument<String>("taskResult")
          print("Native通知任务完成:$taskData")
          // 返回结果给Native
          return "Flutter已收到通知";
        default:
          throw PlatformException(code: "UNKNOWN_METHOD", message: "未实现该方法");
      }
    });
  }
}

// 在main函数中初始化
void main() {
  NativeCallHandler.setupNativeCallListener();
  runApp(MyApp());
}
Android 端(Kotlin)
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.myapp/native_comm"
    private lateinit var methodChannel: MethodChannel

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        // 比如在硬件回调或API请求完成后,主动调用Flutter方法
        triggerNativeCallToFlutter()
    }

    private fun triggerNativeCallToFlutter() {
        // 调用Flutter端的"notifyFlutterTaskDone"方法,携带参数
        methodChannel.invokeMethod(
            "notifyFlutterTaskDone",
            mapOf("taskResult" to "硬件数据采集完成")
        ) { result ->
            if (result.success) {
                val flutterResponse = result.result as String
                println("Flutter返回:$flutterResponse")
            } else {
                println("调用失败:${result.errorMessage}")
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者adamhurwitz.eth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:14:57