在Flutter中,Platform Channels
是一种用于与原生代码(如iOS和Android)进行通信的机制。Flutter提供了三种类型的通道:
- MethodChannel:用于调用平台方法并接收返回值。
- EventChannel:用于接收来自平台的事件流。
- BasicMessageChannel:用于发送和接收字符串和半结构化信息。
MethodChannel
MethodChannel
主要用于 Flutter 应用和原生平台代码之间的双向通信。例如,Flutter 调用 iOS 方法或 iOS 调用 Flutter 方法。
Flutter 端代码
dart
import 'package:flutter/services.dart';
// 定义 MethodChannel
static const platform = const MethodChannel('com.example.flutter/native');
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level is $result%.';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
print(batteryLevel);
}
iOS 端代码 (Objective-C)
objective-c
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel* batteryChannel = [FlutterMethodChannel
methodChannelWithName:@"com.example.flutter/native"
binaryMessenger:controller];
__weak typeof(self) weakSelf = self;
[batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
if ([@"getBatteryLevel" isEqualToString:call.method]) {
int batteryLevel = [weakSelf getBatteryLevel];
if (batteryLevel == -1) {
result([FlutterError errorWithCode:@"UNAVAILABLE"
message:@"Battery info unavailable"
details:nil]);
} else {
result(@(batteryLevel));
}
} else {
result(FlutterMethodNotImplemented);
}
}];
[super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (int)getBatteryLevel {
UIDevice* device = [UIDevice currentDevice];
device.batteryMonitoringEnabled = YES;
if (device.batteryState == UIDeviceBatteryStateUnknown) {
return -1;
} else {
return (int)(device.batteryLevel * 100);
}
}
@end
EventChannel
EventChannel
用于将事件流从平台传递到 Flutter。
Flutter 端代码
dart
static const EventChannel eventChannel = EventChannel('com.example.flutter/charging');
@override
void initState() {
super.initState();
eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
}
void _onEvent(Object event) {
print('Charging status: $event');
}
void _onError(Object error) {
print('Error occurred: $error');
}
iOS 端代码 (Objective-C)
objective-c
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end
@implementation AppDelegate {
FlutterEventSink _eventSink;
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterEventChannel* chargingChannel = [FlutterEventChannel
eventChannelWithName:@"com.example.flutter/charging"
binaryMessenger:controller];
[chargingChannel setStreamHandler:self];
[super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
_eventSink = events;
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
[self sendBatteryStateEvent];
return nil;
}
- (FlutterError*)onCancelWithArguments:(id)arguments {
_eventSink = nil;
return nil;
}
- (void)sendBatteryStateEvent {
UIDeviceBatteryState state = [[UIDevice currentDevice] batteryState];
switch (state) {
case UIDeviceBatteryStateCharging:
_eventSink(@"charging");
break;
case UIDeviceBatteryStateUnplugged:
_eventSink(@"discharging");
break;
default:
_eventSink([FlutterError errorWithCode:@"UNAVAILABLE"
message:@"Battery state unavailable"
details:nil]);
break;
}
}
@end
BasicMessageChannel
BasicMessageChannel
用于发送和接收字符串和半结构化的信息(如JSON)。
Flutter 端代码
dart
static const BasicMessageChannel<String> basicMessageChannel =
BasicMessageChannel<String>('com.example.flutter/basic', StringCodec());
Future<void> sendMessage() async {
try {
String result = await basicMessageChannel.send('Hello from Flutter');
print('Received response: $result');
} catch (e) {
print('Failed to send message: $e');
}
}
iOS 端代码 (Objective-C)
objective-c
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterBasicMessageChannel* messageChannel = [FlutterBasicMessageChannel
messageChannelWithName:@"com.example.flutter/basic"
binaryMessenger:controller];
[messageChannel setMessageHandler:^(id message, FlutterReply reply) {
NSLog(@"Received message from Flutter: %@", message);
reply(@"Hello from iOS");
}];
[super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}
@end
这些通道类型在Flutter和iOS之间提供了灵活且强大的通信机制。通过使用这些通道,可以有效地构建跨平台应用,同时利用平台特定的功能和特性。