一文精通-Flutter 与原生(Android/iOS)通信

Flutter 与原生(Android/iOS)通信主要依靠 Platform Channel 机制,以下是三种基本通信方式及其使用场景,附代码示例:


一、MethodChannel(方法通道)

用途双向通信 ,用于 Flutter 与原生之间调用对方的方法(如调用原生 API 或传递计算结果)。
场景:获取设备信息、调用相机/传感器、支付功能等需要主动触发原生能力的场景。

代码示例:

dart 复制代码
// Flutter 端(Dart)
import 'package:flutter/services.dart';

final methodChannel = MethodChannel('com.example/app');

// 调用原生方法获取电池电量
Future<int> getBatteryLevel() async {
  try {
    final result = await methodChannel.invokeMethod('getBatteryLevel');
    return result as int;
  } on PlatformException catch (e) {
    print("Error: ${e.message}");
    return -1;
  }
}
kotlin 复制代码
// Android 端(Kotlin)
class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/app").setMethodCallHandler { call, result ->
            if (call.method == "getBatteryLevel") {
                val batteryLevel = getBatteryLevel()
                result.success(batteryLevel)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun getBatteryLevel(): Int {
        // 实现获取电量逻辑
    }
}
swift 复制代码
// iOS 端(Swift)
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(name: "com.example/app", binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler { call, result in
            if call.method == "getBatteryLevel" {
                self.getBatteryLevel(result: result)
            } else {
                result(FlutterMethodNotImplemented)
            }
        }
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    private func getBatteryLevel(result: FlutterResult) {
        // 实现获取电量逻辑
    }
}

二、EventChannel(事件通道)

用途单向数据流 ,用于原生向 Flutter 持续发送事件(如传感器数据、网络状态变化)。
场景:实时监听传感器数据、网络连接状态、推送通知等流式数据场景。

代码示例:

csharp 复制代码
// Flutter 端(Dart)
final eventChannel = EventChannel('com.example/events');

Stream<int> listenToTimer() {
  return eventChannel.receiveBroadcastStream().map((event) => event as int);
}

// 使用:StreamBuilder 监听数据
kotlin 复制代码
// Android 端(Kotlin)
class MainActivity : FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        EventChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/events").setStreamHandler(
            object : StreamHandler {
                var eventSink: EventChannel.EventSink? = null
                var timer: Timer? = null

                override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                    eventSink = events
                    timer = Timer().scheduleAtFixedRate(1000, 1000) {
                        eventSink?.success(System.currentTimeMillis())
                    }
                }

                override fun onCancel(arguments: Any?) {
                    timer?.cancel()
                    eventSink = null
                }
            }
        )
    }
}
swift 复制代码
// iOS 端(Swift)
class EventHandler: NSObject, FlutterStreamHandler {
    var eventSink: FlutterEventSink?
    var timer: Timer?

    func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
        self.eventSink = events
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
            events(Int(Date().timeIntervalSince1970))
        }
        return nil
    }

    func onCancel(withArguments arguments: Any?) -> FlutterError? {
        timer?.invalidate()
        eventSink = nil
        return nil
    }
}

// AppDelegate 中注册
let eventChannel = FlutterEventChannel(name: "com.example/events", binaryMessenger: controller.binaryMessenger)
eventChannel.setStreamHandler(EventHandler())

三、BasicMessageChannel(基础消息通道)

用途简单数据传递 ,支持双向通信,适合传递基本数据类型(String/Map)。
场景:轻量级数据交换(如用户配置同步、简单文本传输)。

代码示例:

dart 复制代码
// Flutter 端(Dart)
final messageChannel = BasicMessageChannel<String>('com.example/messages', StringCodec());

// 发送消息
messageChannel.send('Hello from Flutter').then((reply) {
  print('Received reply: $reply');
});

// 设置消息处理器
messageChannel.setMessageHandler((message) async {
  return 'Received: $message';
});
rust 复制代码
// Android 端(Kotlin)
BasicMessageChannel<String>(flutterEngine.dartExecutor.binaryMessenger, "com.example/messages", StringCodec.INSTANCE).apply {
    setMessageHandler { message, reply ->
        reply.reply("Android received: $message")
    }
}
less 复制代码
// iOS 端(Swift)
let messageChannel = FlutterBasicMessageChannel(
    name: "com.example/messages",
    binaryMessenger: controller.binaryMessenger,
    codec: FlutterStringCodec.sharedInstance()
)
messageChannel.setMessageHandler { message, reply in
    reply("iOS received: (message ?? "")")
}

对比总结

通道类型 通信方向 数据流特点 典型场景
MethodChannel 双向 单次方法调用与响应 调用原生 API、获取设备信息
EventChannel 原生 → Flutter 持续事件流 传感器监听、实时数据更新
BasicMessage 双向 简单数据传递 轻量级配置同步、文本交互

根据具体需求选择通道类型,确保数据高效传递并减少性能损耗。

相关推荐
码匠许师傅5 小时前
【C++ 面试真题】30. 聊聊 C++ 的互斥锁与读写锁
java·c++·面试
GitLqr6 小时前
Flutter + Unity 混合开发:用 unity_kit 实现高效的双向通信
flutter·unity3d·全栈
Heo7 小时前
怎么保证缓存和数据库一致性?
前端·后端·面试
众人皆醒我独醉8 小时前
调和循环:kubectl apply 之后发生了什么
面试·llm·gpu
众人皆醒我独醉8 小时前
从 Spec 到资源:Predictor/Transformer/Explainer 如何变成 Deployment
面试·llm·gpu
面试鸭9 小时前
Codex 跑进法务部,周活居然暴涨了 108 倍???
后端·面试·求职
程序员老刘9 小时前
Flutter版本选择指南:3.47压哨发布,9月大限只剩一周 | 2026年8月
flutter·ai编程·客户端
程序员爱钓鱼11 小时前
Rust const泛型详解:让常量也成为泛型参数
后端·面试·rust
黄敬峰11 小时前
一文搞懂 Next.js + AI 全栈开发:为什么它是 2026 年最强的 AI 全栈框架
面试
吴声子夜歌13 小时前
Java面试——数据结构(一)
java·数据结构·面试