我们通过MethodChannel的实现可以两端数据交互MethodChannel都是flutter作为发起方,但如果我们需要监听如音量监听、电量过少等原生广播,MethodChannel并没有这样的能力,所以此时就需要引入EventChannel来解决此问题
我们在untitled1_platform_interface文件定义开启监听同方法,
//untitled1_platform_interface.dart
Future<String?> listenerEvent(EveCounter eveCounter) {
throw UnimplementedError('listenerEvent() has not been implemented.');
}
在untitled1文件中将方法暴露给flutter端
//untitled1.dart
Future<String?> listenerEvent(EveCounter eveCounter) {
print("BBBBBB");
return Untitled1Platform.instance.listenerEvent(eveCounter);
}
在untitled1_platform_channel文件中定义事件响应通道_eventChannel和要监听的事件流对象_streamSubscription并在方法中监听回调
//untitled1_method_channel
static const EventChannel _eventChannel = EventChannel("listenerEvent/event");
StreamSubscription<dynamic>? _streamSubscription;
@override
Future<String?> listenerEvent(EveCounter eveCounter) async {
print("eeeeee");
var _ev ;
_streamSubscription = _eventChannel.receiveBroadcastStream().listen((event) {
_ev = event;
print("=======$_ev========$event");
eveCounter.setMyEve(event);
});
return _ev;
}
因为我们接受回调是在_streamSubscription里接收,我们可以选择把_streamSubscription定义在我们的项目中,也可以使用flutter的ChangeNotifier给一个响应回调,将_streamSubscription隐藏在我们的插件中,
class EveCounter extends ChangeNotifier{
var _myEve;
String get myEve => _myEve.toString();
setMyEve(event){
_myEve = event;
notifyListeners();
}
}
整体代码如下
在项目中接收
EveCounter _eveCounter = new EveCounter();
Future<void> getEv() async{
String eve;
try{
print("aaaaaaa");
eve = await _untitled1Plugin.listenerEvent(_eveCounter)??"1";
print("+++++++$_ev");
}on PlatformException {
eve = "1";
}
_eveCounter.addListener(() {
eve = _eveCounter.myEve .toString();
setState(() {
_ev = eve;
});
});
if (!mounted) return;
setState(() {
_ev = eve;
});
}
至此,flutter端逻辑处理完毕
android端我们需要定义事件派发对象EventSink和事件派发流StreamHandler
我这边是直接在类Untitled1Plugin上实现借口,当然,你也可以重新定义一个类来实现StreamHander,注意EventChannel中传递的字符串要和flutter一致,因为是模拟器,我这边定义了一个计时器模仿android底层广播
StreamChannel中要实现两个方法,onListen()和onCancel();
override fun onListen(arguments: Any?, events: EventSink?) {
eventSink = events
myTime?.start()
}
override fun onCancel(arguments: Any?) {
eventSink = null
}
在onListen中我们将系统获取事件派发对象赋值给我们自己定义的引用上;在onCancel中置空
在我们需要回传的地方调用eventSink?.success(p0)
inner class MyTime():CountDownTimer(20000,1000){
override fun onTick(p0: Long) {
eventSink?.success(p0)
}
override fun onFinish() {
eventSink?.success("完成")
}
}
至此,android端EventChannel结束了,完整代码如下
package com.example.untitled1
import android.os.CountDownTimer
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.EventChannel.EventSink
import io.flutter.plugin.common.EventChannel.StreamHandler
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import java.util.TimerTask
/** Untitled1Plugin */
class Untitled1Plugin: FlutterPlugin, MethodCallHandler ,StreamHandler,ActivityAware{
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel : MethodChannel
private var eventSink: EventSink? = null
private var myTime:MyTime? = null
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "untitled1")
channel.setMethodCallHandler(this)
var eventChannel = EventChannel(flutterPluginBinding.binaryMessenger,"listenerEvent/event")
eventChannel.setStreamHandler(this)
myTime = MyTime()
}
inner class MyTime():CountDownTimer(20000,1000){
override fun onTick(p0: Long) {
eventSink?.success(p0)
}
override fun onFinish() {
eventSink?.success("完成")
}
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
override fun onListen(arguments: Any?, events: EventSink?) {
eventSink = events
myTime?.start()
}
override fun onCancel(arguments: Any?) {
eventSink = null
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
}
override fun onDetachedFromActivityForConfigChanges() {
}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
}
override fun onDetachedFromActivity() {
}
}
IOS端与android端逻辑相同 ;完整IOS端代码
import Flutter
import UIKit
public class SwiftUntitled1Plugin: NSObject, FlutterPlugin,FlutterStreamHandler{
var eventChannel:FlutterEventChannel?
var sink:FlutterEventSink?
var count:Int = 20
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
print("qqqqqqq")
self.sink = events
self.count = 20
countFlutter()
return nil
}
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
self.sink = nil
return nil
}
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "untitled1", binaryMessenger: registrar.messenger())
let instance = SwiftUntitled1Plugin()
let eventChannel = FlutterEventChannel(name: "listenerEvent/event", binaryMessenger: registrar.messenger())
print("ppppppqq")
eventChannel.setStreamHandler(instance)
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
result("iOS " + UIDevice.current.systemVersion)
}
func countFlutter()->Void{
print("++++11111")
Timer.scheduledTimer(withTimeInterval: 1, repeats: true
, block: {(Timer) in
if self.count > 0 {
self.count-=1
self.sink?("111=====\(self.count)")
}else{
self.sink?("1======0")
// self.count-=10
// self.sink?("111=====\(self.count)")
Timer.invalidate()
// Timer.
}
print("------\(self.count)")
})
}
}
至此结束