0、概述
一、BasicMessageChannel
class BasicMessageChannel<T> {
/// The logical channel on which communication happens, not null.
final String name;
/// The message codec used by this channel, not null.
final MessageCodec<T> codec;
/// The messenger which sends the bytes for this channel, not null.
final BinaryMessenger? _binaryMessenger;
/// Creates a [BasicMessageChannel] with the specified [name], [codec] and [binaryMessenger].
///
/// The [name] and [codec] arguments cannot be null. The default [ServicesBinding.defaultBinaryMessenger]
/// instance is used if [binaryMessenger] is null.
const BasicMessageChannel(this.name, this.codec, { BinaryMessenger? binaryMessenger }) : assert(name != null), assert(codec != null), _binaryMessenger = binaryMessenger;
BinaryMessenger get binaryMessenger => _binaryMessenger ?? ServicesBinding.instance!.defaultBinaryMessenger;
}
通用的平台侧交互类,该类实现的功能: 编码数据、发送数据、解码接收到的数据。
二、MethodChannel
class MethodChannel {
/// Creates a [MethodChannel] with the specified [name].
/// The [codec] used will be [StandardMethodCodec], unless otherwise
/// specified.
/// The [name] and [codec] arguments cannot be null. The default [ServicesBinding.defaultBinaryMessenger]
/// instance is used if [binaryMessenger] is null.
const MethodChannel(this.name, [this.codec = const StandardMethodCodec(), BinaryMessenger? binaryMessenger ])
: assert(name != null),
assert(codec != null),
_binaryMessenger = binaryMessenger;
/// The logical channel on which communication happens, not null.
final String name;
/// The message codec used by this channel, not null.
final MethodCodec codec;
/// The messenger used by this channel to send platform messages.
/// The messenger may not be null.
BinaryMessenger get binaryMessenger => _binaryMessenger ?? ServicesBinding.instance!.defaultBinaryMessenger;
final BinaryMessenger? _binaryMessenger;
// 关键函数,比BasicMessageChannel多的功能
@optionalTypeArgs
Future<T?> _invokeMethod<T>(String method, { required bool missingOk, dynamic arguments }) async {
assert(method != null);
// 编码数据,并发送
final ByteData? result = await binaryMessenger.send(
name,
codec.encodeMethodCall(MethodCall(method, arguments)),
);
if (result == null) {
if (missingOk) {
return null;
}
throw MissingPluginException('No implementation found for method $method on channel $name');
}
// 解码数据,返回
return codec.decodeEnvelope(result) as T?;
}
@optionalTypeArgs
Future<T?> invokeMethod<T>(String method, [ dynamic arguments ]) {
return _invokeMethod<T>(method, missingOk: false, arguments: arguments);
}
void setMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler) {
_methodChannelHandlers[this] = handler;
binaryMessenger.setMessageHandler(
name,
handler == null
? null
: (ByteData? message) => _handleAsMethodCall(message, handler),
);
}
}
该类支持发送方法消息。
三、调用平台侧函数的流程
1、flutter 调用平台侧函数
static const platform = MethodChannel('samples.flutter.dev/battery');
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
2、IOS侧的代码
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
// 创建逻辑通道
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery",
binaryMessenger: controller.binaryMessenger)
// 注册收到方法调用的回调
batteryChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
// This method is invoked on the UI thread.
guard call.method == "getBatteryLevel" else {
result(FlutterMethodNotImplemented)
return
}
self?.receiveBatteryLevel(result: result)
})
//注册插件,当查找getBatteryLevel方法的会后,从当前类中查找
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
在AppDelegate.swift 中添加下面的方法:
private func receiveBatteryLevel(result: FlutterResult) {
let device = UIDevice.current
device.isBatteryMonitoringEnabled = true
if device.batteryState == UIDevice.BatteryState.unknown {
result(FlutterError(code: "UNAVAILABLE",
message: "Battery level not available.",
details: nil))
} else {
result(Int(device.batteryLevel * 100))
}
}