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

相关推荐
everyStudy32 分钟前
前端五种排序
前端·算法·排序算法
甜兒.2 小时前
鸿蒙小技巧
前端·华为·typescript·harmonyos
Jiaberrr5 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy5 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白5 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、5 小时前
Web Worker 简单使用
前端
web_learning_3216 小时前
信息收集常用指令
前端·搜索引擎
tabzzz6 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百6 小时前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao6 小时前
自动化测试常用函数
前端·css·html5