flutter 插件学习小记(2)EventChannel

我们通过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)")
        })
    }
    
}

至此结束

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值