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

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

相关推荐
GISer_Jing17 分钟前
Axios面试常见问题详解
前端·javascript·面试
vvilkim1 小时前
Flutter JSON解析全攻略:使用json_serializable实现高效序列化
flutter·json
求职小程序华东同舟求职1 小时前
互联网校招腾讯26届校招暑期实习综合素质测评答题攻略及真题题库
面试·职场和发展·求职招聘·求职
测试19982 小时前
2025软件测试面试题汇总(接口测试篇)
自动化测试·软件测试·python·测试工具·面试·职场和发展·接口测试
LinXunFeng2 小时前
Flutter - GetX Helper 如何应用于旧页面
前端·flutter·开源
星垂野3 小时前
JavaScript 原型及原型链:深入解析核心机制
javascript·面试
zayyo3 小时前
面试官问我,后端一次性返回十万条数据,前端应该怎么处理 ?
前端·javascript·面试
技术蔡蔡3 小时前
从Google IO学习Flutter
flutter·google·google io
工呈士7 小时前
构建优化策略:Tree Shaking、代码分割与懒加载
前端·面试
roman_日积跬步-终至千里9 小时前
【系统设计【1】】系统设计面试方法论:从0到百万用户的需求到架构的推演
面试·架构