我目前正在学习Flutter,特别是如何与设备本身进行通信。
目前我已经设置了一个MethodChannel,我在其中接收一个字符串列表作为结果,但是现在我想将它更改为通过一个EventChannel在流上接收这些字符串。
我知道我仍然需要依赖MethodChannel来触发Android端的方法,然后它通过EventChannel将数据(在我的例子中是String)发送回flutter。但是我真的不知道如何让EventChannel只发送几个流(可能在它们之间有一点延迟),因为我发现的每个关于EventChannel的教程对我来说都是困惑而不是有用的:(
下面是我目前通过EventChannel获取内容的代码:
flutter-plugin:
static const EventChannel messageChannel = EventChannel('eventChannelStream');
Stream<String> get messageStream async* {
messageChannel.receiveBroadcastStream().map((message) {
return message;
});
}android端的Kotlin代码:
class HelperPlugin : FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler {
private lateinit var channel: MethodChannel
private var messageChannel: EventChannel? = null
private var eventSink: EventChannel.EventSink? = null
override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink?) {
this.eventSink = eventSink
}
override fun onCancel(arguments: Any?) {
eventSink = null
messageChannel = null
}
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "methodChannel")
channel.setMethodCallHandler(this)
messageChannel = EventChannel(flutterPluginBinding.binaryMessenger, "eventChannelStream")
messageChannel?.setStreamHandler(this)
}
...
// Doing other stuff here以及我希望如何在BLoC中使用这些消息,以便在事件发生后将它们发送到UI:
Stream<String> retrieveMessage(Stream<String> messageStream) async* {
await for (String message in messageStream) {
//await Future.delayed(const Duration(milliseconds: 1500));
yield message;
}
}发布于 2021-10-22 13:05:19
好了,开始工作了。这可能不是最好的方法,但至少它是有效的:)
下面是我是如何做到的,也许它可以帮助其他人:):
Android响应的Kotlin代码:
class HelperPlugin : FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler {
private lateinit var channel: MethodChannel
private var messageChannel: EventChannel? = null
private var eventSink: EventChannel.EventSink? = null
override fun onListen(arguments: Any?, eventSink: EventChannel.EventSink?) {
this.eventSink = eventSink
}
override fun onCancel(arguments: Any?) {
eventSink = null
messageChannel = null
}
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "methodChannel")
channel.setMethodCallHandler(this)
messageChannel = EventChannel(flutterPluginBinding.binaryMessenger, "eventChannelStream")
messageChannel?.setStreamHandler(this)
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
when (call.method) {
"getPlatformVersion" -> {
result.success(tellVersionNumber())
}
"tellJoke" -> {
result.success(tellJoke())
}
"cantAnswer" -> {
result.success(cantAnswer())
}
"whoAreYou" -> {
result.success(whoAreYou())
}
"currentTime" -> {
result.success(currentTime())
}
"upTime" -> {
result.success(upTime())
}
"greetUser" -> {
result.success(greetUser())
}
"systemInformation" -> {
result.success(systemInformation())
}
else -> {
result.notImplemented()
}
}
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
// Here are Functions, which add Strings to the EventChannel via eventSink?.success("String to Add")
}Flutter-Plugin:
class ChatbotHelper extends ChatbotInterface {
static const MethodChannel _channel = MethodChannel('methodChannel');
static const EventChannel messageChannel = EventChannel('eventChannelStream');
Stream<String> get messageStream async* {
await for (String message in messageChannel.receiveBroadcastStream().map((message) => message)){
yield message;
}
}
@override
Future<void> platformVersion() async {
await _channel.invokeMethod('getPlatformVersion');
}
@override
Future<void> tellJoke() async {
await _channel.invokeMethod('tellJoke');
}
// other invokeMethods and answerQuestion function, which calls these invokeMethods depending on a String message
...
}下面是我如何在我的BLoC中使用流:
Future<void> _initializeAnswerStream(
InitializeMessageStreamEvent event, Emitter<ChatState> emit) async {
try{
await for(String message in retrieveMessageStream(_helper.messageStream)) {
add(AddResponseMessageEvent(responseMessage: message));
}
}catch(e){
print(e);
}
}在我的窗口小部件树中创建相应的BlocProvider时,将调用此BLoC-Event来初始化流并等待消息。
编辑:修复了一些我重命名的值,将其发布在这里
https://stackoverflow.com/questions/69672645
复制相似问题