9.1 平台通道(Platform Channel)

Platform Channel 是 Flutter 与原生平台(Android/iOS)之间通信的桥梁,允许 Dart 代码调用原生 API,或原生代码向 Flutter 推送事件。


一、通信机制概述

复制代码
Flutter (Dart)          Platform Channel          原生 (Java/Swift)
     │                                                    │
     │  MethodChannel.invokeMethod('getBatteryLevel')     │
     │ ─────────────────────────────────────────────────► │
     │                                                    │ 执行原生代码
     │  result: 85                                        │
     │ ◄───────────────────────────────────────────────── │
     │                                                    │
     │  EventChannel.receiveBroadcastStream()             │
     │ ─────────────────────────────────────────────────► │
     │  event: {charging: true}                           │
     │ ◄───────────────────────────────────────────────── │ 原生推送事件

三种 Channel 类型:

Channel 方向 适用场景
MethodChannel 双向,单次调用 调用原生 API,获取返回值
EventChannel 原生 → Flutter,持续流 传感器、电量、网络状态变化
BasicMessageChannel 双向,自定义编解码 低频消息传递

二、MethodChannel

2.1 Flutter 侧

dart 复制代码
class BatteryService {
  static const _channel = MethodChannel('com.example.app/battery');

  static Future<int> getBatteryLevel() async {
    try {
      final level = await _channel.invokeMethod<int>('getBatteryLevel');
      return level ?? -1;
    } on PlatformException catch (e) {
      debugPrint('Battery error: ${e.message}');
      return -1;
    } on MissingPluginException {
      debugPrint('Battery plugin not available');
      return -1;
    }
  }

  static Future<bool> isCharging() async {
    final result = await _channel.invokeMethod<bool>('isCharging');
    return result ?? false;
  }
}

2.2 Android 侧(Kotlin)

kotlin 复制代码
// android/app/src/main/kotlin/.../MainActivity.kt
class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example.app/battery"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "getBatteryLevel" -> {
                        val level = getBatteryLevel()
                        if (level != -1) result.success(level)
                        else result.error("UNAVAILABLE", "Battery not available", null)
                    }
                    "isCharging" -> {
                        result.success(isDeviceCharging())
                    }
                    else -> result.notImplemented()
                }
            }
    }

    private fun getBatteryLevel(): Int {
        val batteryManager = getSystemService(BATTERY_SERVICE) as BatteryManager
        return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
    }
}

2.3 iOS 侧(Swift)

swift 复制代码
// ios/Runner/AppDelegate.swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(
            name: "com.example.app/battery",
            binaryMessenger: controller.binaryMessenger
        )

        channel.setMethodCallHandler { call, result in
            switch call.method {
            case "getBatteryLevel":
                let device = UIDevice.current
                device.isBatteryMonitoringEnabled = true
                if device.batteryState == .unknown {
                    result(FlutterError(
                        code: "UNAVAILABLE",
                        message: "Battery not available",
                        details: nil
                    ))
                } else {
                    result(Int(device.batteryLevel * 100))
                }
            default:
                result(FlutterMethodNotImplemented)
            }
        }

        return super.application(application, didFinishLaunchingWithOptions: options)
    }
}

三、EventChannel

3.1 Flutter 侧(监听流)

dart 复制代码
class NetworkStatusService {
  static const _channel = EventChannel('com.example.app/network');

  static Stream<bool> get onConnectivityChanged {
    return _channel
        .receiveBroadcastStream()
        .map((event) => event as bool);
  }
}

// 使用
class ConnectivityWidget extends StatefulWidget { ... }
class _State extends State<ConnectivityWidget> {
  StreamSubscription? _sub;
  bool _isConnected = true;

  @override
  void initState() {
    super.initState();
    _sub = NetworkStatusService.onConnectivityChanged.listen((connected) {
      setState(() => _isConnected = connected);
    });
  }

  @override
  void dispose() {
    _sub?.cancel();
    super.dispose();
  }
}

3.2 Android 侧(Kotlin)

kotlin 复制代码
class ConnectivityStreamHandler(context: Context) : EventChannel.StreamHandler {
    private val connectivityManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    private var callback: ConnectivityManager.NetworkCallback? = null

    override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
        callback = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                events.success(true)
            }
            override fun onLost(network: Network) {
                events.success(false)
            }
        }
        connectivityManager.registerDefaultNetworkCallback(callback!!)
    }

    override fun onCancel(arguments: Any?) {
        callback?.let { connectivityManager.unregisterNetworkCallback(it) }
        callback = null
    }
}

四、BasicMessageChannel

dart 复制代码
// 双向通信(不需要请求-响应模式,适合消息传递)
static const _messageChannel = BasicMessageChannel<String>(
  'com.example.app/messages',
  StringCodec(),
);

// 发送消息到原生
await _messageChannel.send('Hello from Flutter');

// 监听来自原生的消息
_messageChannel.setMessageHandler((message) async {
  print('Message from native: $message');
  return 'Flutter received: $message'; // 可选的回复
});

小结

Channel 场景
MethodChannel Flutter 调原生 API,一次性调用返回结果
EventChannel 原生持续推送数据(传感器/网络/电量)
BasicMessageChannel 轻量双向消息

👉 下一节:9.2 原生插件开发

相关推荐
大猫熊猫2 小时前
vivo审核不通过,flutter读取剪贴板内容
flutter
恋猫de小郭3 小时前
compose_skill 和 android skills,对 Android 项目提升巨大的专家 AI Skills
android·前端·flutter
空中海3 小时前
5.3 本地存储
flutter
空中海4 小时前
9.4 推送通知
flutter
星释5 小时前
鸿蒙Flutter实战:30.在Pub上发布鸿蒙化插件
flutter·harmonyos·鸿蒙
nice先生的狂想曲5 小时前
flutter布局(列表组件)
flutter
见山是山-见水是水5 小时前
鸿蒙flutter第三方库适配 - 动态工作流
flutter·华为·harmonyos
yeziyfx5 小时前
Flutter SingleChildScrollView内部ListView滑动不了
flutter
Zender Han5 小时前
VS Code 开发 Flutter 常用快捷键和插件工具详解
android·vscode·flutter·ios