一文精通-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 双向 简单数据传递 轻量级配置同步、文本交互

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

相关推荐
Enddme14 分钟前
《面试必问:为什么Promise比setTimeout先执行?事件循环的魔鬼细节》
前端·面试
uhakadotcom38 分钟前
解锁 Google Cloud Pub/Sub 的强大功能
后端·面试·github
马拉萨的春天1 小时前
mac 下配置flutter 总是失败,请参考文章重新配置flutter 环境MacOS Flutter环境配置和安装
flutter·macos
uhakadotcom1 小时前
Vulkan API 入门指南:跨平台、高性能的图形和计算解决方案
后端·面试·github
uhakadotcom2 小时前
Meta Horizon OS 开发工具:打造更好的 MR/VR 体验
javascript·后端·面试
uhakadotcom2 小时前
刚刚发布的React 19.1提供了什么新能力?
前端·javascript·面试
uhakadotcom2 小时前
Rust中的reqwest库:轻松实现HTTP请求
后端·面试·github
uhakadotcom2 小时前
Expo 简介:跨平台移动应用开发的强大工具
前端·javascript·面试
uhakadotcom2 小时前
Apache APISIX 简介与实践
后端·面试·github
uhakadotcom2 小时前
Kong Gateway 简介与实践
后端·面试·github