Jansiel Notes

Flutter Channel 类型与用法

在Flutter中, Platform Channels 是一种用于与原生代码(如iOS和Android)进行通信的机制。Flutter提供了三种类型的通道:

  1. MethodChannel:用于调用平台方法并接收返回值。
  2. EventChannel:用于接收来自平台的事件流。
  3. BasicMessageChannel:用于发送和接收字符串和半结构化信息。

MethodChannel

MethodChannel 主要用于 Flutter 应用和原生平台代码之间的双向通信。例如,Flutter 调用 iOS 方法或 iOS 调用 Flutter 方法。

Flutter 端代码

 1import 'package:flutter/services.dart';
 2
 3// 定义 MethodChannel
 4static const platform = const MethodChannel('com.example.flutter/native');
 5
 6Future<void> _getBatteryLevel() async {
 7  String batteryLevel;
 8  try {
 9    final int result = await platform.invokeMethod('getBatteryLevel');
10    batteryLevel = 'Battery level is $result%.';
11  } on PlatformException catch (e) {
12    batteryLevel = "Failed to get battery level: '${e.message}'.";
13  }
14
15  print(batteryLevel);
16}
17

iOS 端代码 (Objective-C)

 1#import <Flutter/Flutter.h>
 2#import <UIKit/UIKit.h>
 3
 4@interface AppDelegate : FlutterAppDelegate
 5@end
 6
 7@implementation AppDelegate
 8
 9- (BOOL)application:(UIApplication *)application
10    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
11  FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
12  FlutterMethodChannel* batteryChannel = [FlutterMethodChannel
13                                          methodChannelWithName:@"com.example.flutter/native"
14                                          binaryMessenger:controller];
15
16  __weak typeof(self) weakSelf = self;
17  [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
18    if ([@"getBatteryLevel" isEqualToString:call.method]) {
19      int batteryLevel = [weakSelf getBatteryLevel];
20
21      if (batteryLevel == -1) {
22        result([FlutterError errorWithCode:@"UNAVAILABLE"
23                                   message:@"Battery info unavailable"
24                                   details:nil]);
25      } else {
26        result(@(batteryLevel));
27      }
28    } else {
29      result(FlutterMethodNotImplemented);
30    }
31  }];
32
33  [super application:application didFinishLaunchingWithOptions:launchOptions];
34  return YES;
35}
36
37- (int)getBatteryLevel {
38  UIDevice* device = [UIDevice currentDevice];
39  device.batteryMonitoringEnabled = YES;
40  if (device.batteryState == UIDeviceBatteryStateUnknown) {
41    return -1;
42  } else {
43    return (int)(device.batteryLevel * 100);
44  }
45}
46
47@end
48

EventChannel

EventChannel 用于将事件流从平台传递到 Flutter。

Flutter 端代码

 1static const EventChannel eventChannel = EventChannel('com.example.flutter/charging');
 2
 3@override
 4void initState() {
 5  super.initState();
 6  eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
 7}
 8
 9void _onEvent(Object event) {
10  print('Charging status: $event');
11}
12
13void _onError(Object error) {
14  print('Error occurred: $error');
15}
16

iOS 端代码 (Objective-C)

 1#import <Flutter/Flutter.h>
 2#import <UIKit/UIKit.h>
 3
 4@interface AppDelegate : FlutterAppDelegate
 5@end
 6
 7@implementation AppDelegate {
 8  FlutterEventSink _eventSink;
 9}
10
11- (BOOL)application:(UIApplication *)application
12    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
13  FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
14
15  FlutterEventChannel* chargingChannel = [FlutterEventChannel
16                                          eventChannelWithName:@"com.example.flutter/charging"
17                                          binaryMessenger:controller];
18
19  [chargingChannel setStreamHandler:self];
20
21  [super application:application didFinishLaunchingWithOptions:launchOptions];
22  return YES;
23}
24
25- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
26  _eventSink = events;
27  [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
28  [self sendBatteryStateEvent];
29  return nil;
30}
31
32- (FlutterError*)onCancelWithArguments:(id)arguments {
33  _eventSink = nil;
34  return nil;
35}
36
37- (void)sendBatteryStateEvent {
38  UIDeviceBatteryState state = [[UIDevice currentDevice] batteryState];
39  switch (state) {
40    case UIDeviceBatteryStateCharging:
41      _eventSink(@"charging");
42      break;
43    case UIDeviceBatteryStateUnplugged:
44      _eventSink(@"discharging");
45      break;
46    default:
47      _eventSink([FlutterError errorWithCode:@"UNAVAILABLE"
48                                     message:@"Battery state unavailable"
49                                     details:nil]);
50      break;
51  }
52}
53
54@end
55

BasicMessageChannel

BasicMessageChannel 用于发送和接收字符串和半结构化的信息(如JSON)。

Flutter 端代码

 1static const BasicMessageChannel<String> basicMessageChannel =
 2    BasicMessageChannel<String>('com.example.flutter/basic', StringCodec());
 3
 4Future<void> sendMessage() async {
 5  try {
 6    String result = await basicMessageChannel.send('Hello from Flutter');
 7    print('Received response: $result');
 8  } catch (e) {
 9    print('Failed to send message: $e');
10  }
11}
12

iOS 端代码 (Objective-C)

 1#import <Flutter/Flutter.h>
 2#import <UIKit/UIKit.h>
 3
 4@interface AppDelegate : FlutterAppDelegate
 5@end
 6
 7@implementation AppDelegate
 8
 9- (BOOL)application:(UIApplication *)application
10    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
11  FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
12  FlutterBasicMessageChannel* messageChannel = [FlutterBasicMessageChannel
13                                                messageChannelWithName:@"com.example.flutter/basic"
14                                                binaryMessenger:controller];
15
16  [messageChannel setMessageHandler:^(id message, FlutterReply reply) {
17    NSLog(@"Received message from Flutter: %@", message);
18    reply(@"Hello from iOS");
19  }];
20
21  [super application:application didFinishLaunchingWithOptions:launchOptions];
22  return YES;
23}
24
25@end
26

这些通道类型在Flutter和iOS之间提供了灵活且强大的通信机制。通过使用这些通道,可以有效地构建跨平台应用,同时利用平台特定的功能和特性。