PlatformChannel功能簡介
PlatformChannel分為BasicMessageChannel傀顾、MethodChannel以及EventChannel三種。其各自的主要用途如下:
- BasicMessageChannel: 用于傳遞數(shù)據(jù)忿族。Flutter與原生項(xiàng)目的資源是不共享的锣笨,可以通過BasicMessageChannel來獲取Native項(xiàng)目的圖標(biāo)等資源蝌矛。
- MethodChannel: 傳遞方法調(diào)用。Flutter主動調(diào)用Native的方法错英,并獲取相應(yīng)的返回值入撒。比如獲取系統(tǒng)電量,發(fā)起Toast等調(diào)用系統(tǒng)API椭岩,可以通過這個來完成茅逮。
- EventChannel: 傳遞事件。這里是Native將事件通知到Flutter判哥。比如Flutter需要監(jiān)聽網(wǎng)絡(luò)情況献雅,這時候MethodChannel就無法勝任這個需求了。EventChannel可以將Flutter的一個監(jiān)聽交給Native塌计,Native去做網(wǎng)絡(luò)廣播的監(jiān)聽挺身,當(dāng)收到廣播后借助EventChannel調(diào)用Flutter注冊的監(jiān)聽,完成對Flutter的事件通知锌仅。
其實(shí)可以看到章钾,無論傳方法還是傳事件,其本質(zhì)上都是數(shù)據(jù)的傳遞热芹,不過上層包的一些邏輯不同而已贱傀。
具體實(shí)現(xiàn)
BasicMessageChannel
初始直接在Native端發(fā)送消息, flutter是收不到的, 因?yàn)檫€沒有執(zhí)行接收監(jiān)聽方法, 所以在Native端發(fā)送消息, 需要注意一下時機(jī)
flutter
static const messageChannel = const BasicMessageChannel('samples.flutter.io/message', StandardMessageCodec());
static const messageChannel2 = const BasicMessageChannel('samples.flutter.io/message2', StandardMessageCodec());
Future<String> sendMessage() async {
String reply = await messageChannel.send('發(fā)送給Native端的數(shù)據(jù)');
print('reply: $reply');
return reply;
}
void receiveMessage() {
messageChannel2.setMessageHandler((message) async {
print('message: $message');
return '返回Native端的數(shù)據(jù)';
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
receiveMessage();
sendMessage();
}
ios
// 初始化定義
FlutterBasicMessageChannel* messageChannel = [FlutterBasicMessageChannel messageChannelWithName:@"samples.flutter.io/message" binaryMessenger:controller];
// 接收消息監(jiān)聽
[messageChannel setMessageHandler:^(id message, FlutterReply callback) {
NSLog(message);
callback(@"返回flutter端的數(shù)據(jù)");
}];
// 觸發(fā)事件執(zhí)行
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterBasicMessageChannel* messageChannel2 = [FlutterBasicMessageChannel messageChannelWithName:@"samples.flutter.io/message2" binaryMessenger:controller];
// 發(fā)送消息
[messageChannel2 sendMessage:(@"發(fā)送給flutter的數(shù)據(jù)") reply:^(id reply) {
NSLog(reply);
}];
android
BasicMessageChannel<Object> messageChannel = new BasicMessageChannel<Object>(getFlutterView(), "samples.flutter.io/message", StandardMessageCodec.INSTANCE);
// 接收消息監(jiān)聽
messageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<Object>() {
@Override
public void onMessage(Object o, BasicMessageChannel.Reply<Object> reply) {
System.out.println("onMessage: " + o);
reply.reply("返回給flutter的數(shù)據(jù)");
}
});
// 觸發(fā)事件執(zhí)行
BasicMessageChannel<Object> messageChannel2 = new BasicMessageChannel<Object>(getFlutterView(), "samples.flutter.io/message2", StandardMessageCodec.INSTANCE);
// 發(fā)送消息
messageChannel2.send("發(fā)送給flutter的數(shù)據(jù)", new BasicMessageChannel.Reply<Object>() {
@Override
public void reply(Object o) {
System.out.println("onReply: " + o);
}
});
MethodChannel
flutter
static const platform = const MethodChannel('samples.flutter.io/battery');
Future<Null> _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;
});
}
// 執(zhí)行_getBatteryLevel方法
ios
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel* batteryChannel = [FlutterMethodChannel
methodChannelWithName:@"samples.flutter.io/battery"
binaryMessenger:controller];
[batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
// TODO
if ([@"getBatteryLevel" isEqualToString:call.method]) {
int batteryLevel = [self getBatteryLevel];
if (batteryLevel == -1) {
result([FlutterError errorWithCode:@"UNAVAILABLE"
message:@"Battery info unavailable"
details:nil]);
} else {
result(@(batteryLevel));
}
} else {
result(FlutterMethodNotImplemented);
}
}];
- (int)getBatteryLevel {
UIDevice* device = UIDevice.currentDevice;
device.batteryMonitoringEnabled = YES;
if (device.batteryState == UIDeviceBatteryStateUnknown) {
return -1;
} else {
return (int)(device.batteryLevel * 100);
}
}
android
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
// TODO
if (call.method.equals("getBatteryLevel")) {
int batteryLevel = getBatteryLevel();
if (batteryLevel != -1) {
result.success(batteryLevel);
} else {
result.error("UNAVAILABLE", "Battery level not available.", null);
}
} else {
result.notImplemented();
}
}
}
);
private int getBatteryLevel() {
int batteryLevel = -1;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
} else {
Intent intent = new ContextWrapper(getApplicationContext()).
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
}
return batteryLevel;
}
FlutterEventChannel
flutter
static const EventChannel _eventChannel =
const EventChannel('samples.flutter.io/test');
void _onEvent(Object event) {
print('返回的內(nèi)容: $event');
}
void _onError(Object error) {
print('返回的錯誤');
}
@override
void initState() {
// TODO: implement initState
super.initState();
// 監(jiān)聽開始
_eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
}
ios
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"samples.flutter.io/test" binaryMessenger:controller];
[eventChannel setStreamHandler:self];
FlutterEventSink eventSink;
// // 這個onListen是Flutter端開始監(jiān)聽這個channel時的回調(diào),第二個參數(shù) EventSink是用來傳數(shù)據(jù)的載體伊脓。
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
eventSink:(FlutterEventSink)events {
eventSink = events;
// arguments flutter給native的參數(shù)
// 回調(diào)給flutter府寒, 建議使用實(shí)例指向,因?yàn)樵揵lock可以使用多次
if (events) {
events(@"主動發(fā)送通知到flutter");
}
// 監(jiān)聽電池狀態(tài)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onBatteryStateDidChange:)
name:UIDeviceBatteryStateDidChangeNotification
object:nil];
return nil;
}
/// flutter不再接收
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
// arguments flutter給native的參數(shù)
[[NSNotificationCenter defaultCenter] removeObserver:self];
eventSink = nil;
return nil;
}
- (void)onBatteryStateDidChange:(NSNotification*)notification {
if (eventSink == nil) return;
UIDeviceBatteryState state = [[UIDevice currentDevice] batteryState];
switch (state) {
case UIDeviceBatteryStateFull:
case UIDeviceBatteryStateCharging:
eventSink(@"charging");
break;
case UIDeviceBatteryStateUnplugged:
eventSink(@"discharging");
break;
default:
eventSink([FlutterError errorWithCode:@"UNAVAILABLE"
message:@"Charging status unavailable"
details:nil]);
break;
}
}
android
new EventChannel(getFlutterView(), CHANNEL2).setStreamHandler(
new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
this.eventSink = eventSink;
handler.sendEmptyMessageDelayed(1, 1000);
}
@Override
public void onCancel(Object o) {
}
private EventChannel.EventSink eventSink;
private int count = 0;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
eventSink.success((count++) + "主動發(fā)送消息給flutter");
// handler.sendEmptyMessageDelayed(1,1000);
}
};
}
);