flutter插件基础之调用EventChannel的简单使用(三)

本篇开始之前,废话不多说,先上效果如下所示:

flutter和原生互传效果.gif

首先,本篇开始讲解EventChannel的使用,


千里之行,始于足下

三.EventChannel的使用

上篇中,我们提到通过MethodChannel的实现可以使flutter端可以随时随地的调用到原生端的如设备版本号,电量等系统信息,并及时返回给flutter端;但是诸如原生端声音音量的改变,电池电量的减少(如电池电量少于20%)时要主动通知到flutter端,MethodChannel并没有这样的能力,所以此时就需要引入EventChannel来解决此问题。

1.EventChannel基本介绍

通过前文EventChannel和MethodChannel的实现流程的异同点分析,我们知道了EventChannel的实现主要分为以下2个步骤,即为如何设置flutter的监听以及原生调用flutter的流程:

1.1.flutter监听流程

首先我们可以在flutter的example/lib/more_Params_page.dart 类或者插件类 lib/flutter_plugin_demo2.dart 类中定义事件响应通道_eventChannel和要监听的事件流对象_streamSubscription,如下所示:

static const EventChannel? _eventChannel = EventChannel("flutter_show_alert/event");
StreamSubscription<dynamic>? _streamSubscription;

在当前类的initState初始化方法中加入需要监听的代码为:

_streamSubscription =  _eventChannel?.receiveBroadcastStream().listen((event) {
  final Map<dynamic,dynamic> map = event;
  String? key = map["key"];
  int? value = map["value"];
  print("handle on ---$key---$value");
  if(map["key"] == "changeVoice"){
  }
  else if(map["key"] == "getCount") {
    setState(() {
            productCount = value;
          });
  }
},onError: errorEventListen,onDone:doneEventListen,) as StreamSubscription;

分别实现对应的 errorEventListen 和 doneEventListen 方法后,如此在flutter端监听的内容设置完毕。

注意:为了更多减少流程,这里是以比较直接的在flutter代码的example/lib/more_Params_page.dart中加入监听原生端代码为例的;
当然,实际开发中可能监听的内容不止一个,建议在插件类 lib/flutter_plugin_demo2.dart类中进行监听,然后根据不同的key分发给flutter代码层,这样会比较好理解一些。

1.2.原生(以安卓为例)调用流程

当flutter端监听的准备工作完成后,需要在安卓原生类FlutterPluginDemo2Plugin.java中加入需要调用的代码,同样主要分为3个步骤。

1.事件派发对象和派发流的定义
定义事件派发对象和派发流代码如下,在派发流的onListen方法中把系统获取事件派发对象赋值给我们定义的事件派发对象,当系统取消事件派发流时,则把事件派发对象置空即可;

// 事件派发对象
private  EventChannel.EventSink eventSink = null;
// 事件派发流
private  EventChannel.StreamHandler streamHandler = new  EventChannel.StreamHandler(){
  @Override
  public void onListen(Object arguments, EventChannel.EventSink events) {
    eventSink = events;
  }

  @Override
  public void onCancel(Object arguments) {
    eventSink = null;
  }
};

2.派发流的初始化和注册

// 初始化事件
EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_show_alert/event");
eventChannel.setStreamHandler(streamHandler);

在onAttachedToEngine 方法中对EventChannel对象进行初始化,保证这里的"flutter_show_alert/event"
要和flutter中的保持一致
,并把我们定义的事件派发流设置给EventChannel去进行管理。

3.事件派发流回传flutter

在需要的地方执行

eventSink.success(map);

即可把要传递的对象回传给flutter。
当然,需要注意的是,在执行eventSink之前需要判空,避免eventSink对象被取消时时,导致崩溃。

2.借助EventChannel实现音量实时监听功能

如开篇所示gif效果图,这里以flutter中设置监听,在原生的iOS端点击音量键后把音量值实时传递给flutter,并在flutter中进行显示的功能

2.1.Flutter端

在example/lib/more_Params_page.dart类中,设置监听的内容(这里只关心changeVoice的key

// 方法2:在需要调用的地方设置监听(各自派发)
_streamSubscription =  _eventChannel?.receiveBroadcastStream().listen((event) {
  final Map<dynamic,dynamic> map = event;
  String? key = map["key"];
  // int? value = map["value"];
  print("handle on ---$key---${map["value"]}");
  if(map["key"] == "changeVoice"){
    setState(() {
      nowVoice = map["value"];
    });
  }
  else if(map["key"] == "getCount") {
    setState(() {
            productCount = map["value"];
          });
  }
},onError: errorEventListen,onDone:doneEventListen,) as StreamSubscription;

2.2.Native(iOS)端

在 FlutterPluginDemo2Plugin.m类中编写代码如下所示:

1.在registerWithRegistrar方法中同MethodChannel对象,初始化注册EventChannel对象如下

FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter_show_alert/event"  binaryMessenger:[registrar messenger]];
    [eventChannel setStreamHandler:instance];

注意:这里的instance是当前类的对象,为了后续可能有其他地方用到当前类,所以这里用单例实现获取该对象

2.遵循FlutterStreamHandler类协议
实现其onListenWithArguments和onCancelWithArguments方法(具体实现同安卓)

3.音量按键通知的监听
在onListenWithArguments方法中设置iOS的音量通知代码如下所示

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(systemVolumChanged:)name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];

4.监听音量变化时把音量值回传给flutter

在音量键通知回调方法中执行

 self.eventSink(dic);

把相关信息包装在dic对象中,回传给flutter进行实时显示音量值大小

注意:在测试修改原生音量的情况下,iOS的设备记得用真机来调测,因为有段时间没搞了,竟然在这个问题上费了很长时间。😭😭

可以看到安卓和iOS相比而言,基本大同小异,整体来说安卓实现3个步骤,iOS是4个步骤,主要问题在于安卓的派发流的定义和FlutterStreamHandler协议实现在同一步骤之中,而iOS则分了2步,当然主要是因为flutter底层中对iOS这块接口的定义是采用协议的形式,如果采用block的方式,也是可以实现同安卓的3步。

好了,通过本篇对EventChannel的讲解说明,可以发现EventChannel主要目的是实现原生可随时通知到flutter,而上篇的MethodChannel对象则实现的是flutter调用安卓的功能,如此二者形成了一个闭环,可以互相调用对方的方法,如此很自然的,就会想到原生擅长什么,flutter擅长什么,二者是不是可以融合在一起,很自然的混合开发就出现了。
不过别着急,在我们研究混合开发之前我们先解决另一个小问题,发现没,现在做到的是flutter和native之间数据的打通互传,但是当把原生view界面如何在flutter中显示,比如常见的地图,直播类的原生界面如何在flutter上完美展现,这个问题,我们下次再来研究。

flutter插件基础之调用MethodChannel的基本使用(二)

本篇,完~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容