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之间提供了灵活且强大的通信机制。通过使用这些通道,可以有效地构建跨平台应用,同时利用平台特定的功能和特性。

相关推荐
candyTong7 小时前
一觉醒来,大模型就帮我排查完页面性能问题
前端·javascript·架构
魔术师Grace7 小时前
我给 AI 做了场入职培训
前端·程序员
玩嵌入式的菜鸡7 小时前
网页访问单片机设备---基于mqtt
前端·javascript·css
前端一小卒8 小时前
我用 Claude Code 的 Superpowers 技能链写了个服务,部署前差点把服务器搞炸
前端·javascript·后端
滑雪的企鹅.9 小时前
HTML头部元信息避坑指南大纲
前端·html
一拳不是超人9 小时前
老婆天天吵吵要买塔罗牌,我直接用 AI 2 小时写了个在线塔罗牌
前端·ai编程
excel11 小时前
如何解决 Nuxt DevTools 中关于 unstorage 包的报错
前端
Rust研习社11 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
C澒11 小时前
AI 生码 - API2Code:接口智能匹配与 API 自动化生码全链路设计
前端·低代码·ai编程
浔川python社11 小时前
HTML头部元信息避坑指南技术文章大纲
前端·html