使用上跟MethodChannel
类似,EventChannel
即为MethodChannel
与Stream
的结合
Flutter 端:
首先同样先建立Channel
并指定名称(记得所有通道名称都不能重复),然後要对Native 端传递来的讯息进行监听,通过EventChannel
调用receiveBroadcastStream()
来取得一个Stream
物件,後续通过在Stream
中新增监听来完成对 Native 端讯息的接收等操作
lib/batterylevel.dart
:
这边建立一个EvnetChannel
来取得Native 端一个骰子持续摇出来的数字,并建立一个取得骰子讯息的Stream
物件方法
static const EventChannel _eventChannel = const EventChannel('dice_number');
static Stream<int> get getRandomNumberStream {
return _eventChannel.receiveBroadcastStream().cast();
}
Native 端(Android):
android/.../BatterylevelPlugin.kt
:
这边一样要设置好EvnetChannel
,指定名称(需要与Flutter 端使用的EvnetChannel
名称相对应),并通过EvnetChannel
呼叫setStreamHandler
来注册一个MessageHandler
来接收此通道讯息,这边不像预设的范例直接让BatterylevelPlugin
实现setStreamHandler
的接口,我们将接口的实现拉出来一个类别来实作,这样把实现接口的逻辑拉出去实作,BatterylevelPlugin
才不会在功能变多时变得太复杂
所以建立一个RandomNumberStreamHandler.kt
来实现接口,这边每一秒骰一次骰子并将结果回传至Flutter 端
class RandomNumberStreamHandler : EventChannel.StreamHandler {
private var sink: EventChannel.EventSink? = null
private var handler: Handler? = null
private val runnable = Runnable {
sendNewRandomNumber()
}
private fun sendNewRandomNumber() {
val randomNumber = (1..6).random()
sink?.success(randomNumber)
handler?.postDelayed(runnable, 1000)
}
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
sink = events
handler = Handler()
handler?.post(runnable)
}
override fun onCancel(arguments: Any?) {
sink = null
handler?.removeCallbacks(runnable)
}
}
BatterylevelPlugin.kt
加上:
private lateinit var eventChannel: EventChannel
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
//Added
eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, "dice_number")
eventChannel.setStreamHandler(RandomNumberStreamHandler())
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
//Added
eventChannel.setStreamHandler(null)
}
Native 端(iOS):
一样可以把setStreamHandler
的接口实现的逻辑拉出去实作,同样建立一个RandomNumberStreamHandler.swift
来实现接口,每一秒骰一次骰子并将结果回传至Flutter 端
ios/Classes/RandomNumberStreamHandler.swift
import Foundation
import Flutter
class RandomNumberStreamHandler: NSObject, FlutterStreamHandler{
var sink: FlutterEventSink?
var timer: Timer?
@objc func sendNewRandomNumber() {
guard let sink = sink else { return }
let randomNumber = Int.random(in: 1..<7)
sink(randomNumber)
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
sink = events
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(sendNewRandomNumber), userInfo: nil, repeats: true)
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
sink = nil
timer?.invalidate()
return nil
}
}
ios/Classes/SwiftBatterylevelPlugin.swift
:
import Flutter
import UIKit
public class SwiftBatterylevelPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
//Added
let eventChannel = FlutterEventChannel(name: "dice_number", binaryMessenger: registrar.messenger())
let randomNumberStreamHandler = RandomNumberStreamHandler()
eventChannel.setStreamHandler(randomNumberStreamHandler)
}
}
今天会分享如何搭配 Realm 实作出资料管理系统,然後用 TableView 显示。 成品: 在 ...
终於来到第30天了,每天写下来不知不觉就一个月了,记得第一课还在自我介绍, 转眼间已经要第三十课。这...
https://github.com/PacktPublishing/Machine-Learni...
InstagramBasicDisplayApiPlugin class InstagramBasi...
并发 vs并行 并发运算就是多线程运算,且并发(concurrency)并非并行(Paralleli...