Flutter Channel 类型与用法

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

  1. MethodChannel:用于调用平台方法并接收返回值。
  2. EventChannel:用于接收来自平台的事件流。
  3. 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之间提供了灵活且强大的通信机制。通过使用这些通道,可以有效地构建跨平台应用,同时利用平台特定的功能和特性。

相关推荐
paopaokaka_luck37 分钟前
基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
前端·javascript·vue.js·spring boot·后端·小程序·uni-app
患得患失9491 小时前
【前端】【vscode】【.vscode/settings.json】为单个项目配置自动格式化和开发环境
前端·vscode·json
飛_1 小时前
解决VSCode无法加载Json架构问题
java·服务器·前端
YGY Webgis糕手之路4 小时前
OpenLayers 综合案例-轨迹回放
前端·经验分享·笔记·vue·web
90后的晨仔4 小时前
🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?
前端·vue.js
Ares-Wang4 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
90后的晨仔4 小时前
Vue 模板语法完全指南:从插值表达式到动态指令,彻底搞懂 Vue 模板语言
前端·vue.js
德育处主任5 小时前
p5.js 正方形square的基础用法
前端·数据可视化·canvas
烛阴5 小时前
Mix - Bilinear Interpolation
前端·webgl
90后的晨仔5 小时前
Vue 3 应用实例详解:从 createApp 到 mount,你真正掌握了吗?
前端·vue.js