Flutter 混合开发 (交互通信)

栏目: IOS · Android · 发布时间: 6年前

内容简介:上篇我们介绍了 Flutter 模块集成到已有的项目工程,接下来我们看看 Native 跟 Flutter 间的交互问题。Flutter 与原生之间的通信依赖灵活的消息传递方式:1,Flutter 部分通过平台通道将消息发送到其应用程序的所在的宿主环境(原生应用)。

上篇我们介绍了 Flutter 模块集成到已有的项目工程,接下来我们看看 Native 跟 Flutter 间的交互问题。

交互通信

Flutter 与原生之间的通信依赖灵活的消息传递方式:

1,Flutter 部分通过平台通道将消息发送到其应用程序的所在的宿主环境(原生应用)。

2,宿主环境通过监听平台通道,接收消息。然后它会调用平台的 API,响应 Flutter 发送的消息。

Flutter主动 调用 宿主环境

在 Flutter 中通过 MethodChannel 的 API 可以发送与方法相对于的消息,宿主环境 iOS 中通过 FlutterMethodChannel 接受方法的调用并返回结果。

Flutter 需要引入 services.dart 模块才可以使用 MethodChannel

import 'package:flutter/services.dart';

Flutter 中的调用代码

const methodChannel = const MethodChannel("com.pages.flutter/call_native");
RaisedButton(
        child: Text("call_native_method_no_params"),
        onPressed: (){
                 methodChannel.invokeMethod("call_native_method_no_params",null);
        },
      ),
      RaisedButton(
        child: Text("call_native_method_params"),
        onPressed: (){
          Map<String,String> params = {"params":"flutter params"};
          methodChannel.invokeMethod("call_native_method_params",params);
        },
      ),
      RaisedButton(
        child: Text("call_native_method_native_result_callback"),
        onPressed: (){
          _nativeCallbackWithParams();
        },
      ),
      Text(_content,style: TextStyle(color: Colors.red),)
Future<Null> _nativeCallbackWithParams() async{
  dynamic result;
  try {
      result = await methodChannel.invokeMethod(
            "call_native_method_native_result_callback", null);
  } on PlatformException catch (e) {
    result = "Failed to get params: '${e.message}'.";
  }
  setState(() {
    _content = result;
  });
}

iOS 中的调用代码

FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
flutterViewController.fd_prefersNavigationBarHidden = YES;
FlutterMethodChannel * messageChannel = [FlutterMethodChannel methodChannelWithName:@"com.pages.flutter/call_native" binaryMessenger:flutterViewController];
[messageChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        NSLog(@"flutter call native:\n method=%@ \n arguments = %@",call.method,call.arguments);
        if ([call.method isEqualToString:@"call_native_method_native_result_callback"]) {
            if (result) {
                result(@"flutter hello");
            }
        }else if([call.method isEqualToString:@"call_native_method_pop_flutter_nav"]){
            [weakSelf.navigationController popViewControllerAnimated:YES];
        }
    }];
[self.navigationController pushViewController:flutterViewController animated:YES];

分别看下控制台输出:

flutter call native
method=call_native_method_no_params 
arguments = (null)
flutter call native
method=call_native_method_params 
arguments = {
  params = "flutter params";
}

第三个事件会在 Flutter 页面显示flutter hello 该值由宿主环境返回。

注意:这里有个设计上的细节,上节提到过就是导航栏的问题,因为宿主环境有个导航栏,而 Flutter 自身也有导航栏,出现了矛盾,到底我们应该保留宿主环境的,还是 Flutter 页面使用自身,隐藏宿主环境的导航栏。我个人觉得后则更合理,Flutter 页面更了解自己导航栏具体功能、主题、交互及显示,我们只需要处理点击返回按钮 pop 回到宿主环境中,如下:

appBar: AppBar(
      title: Text('Flutter Page') ,
      leading: IconButton(icon: Icon(Icons.arrow_back_ios), onPressed:()=>methodChannel.invokeMethod("call_native_method_pop_flutter_nav",null)),
    ),

我们只需要在宿主环境中监听到该事件后调用导航的 pop 功能。

宿主环境主动调用 Flutter

一般可以用作宿主环境为 Flutter 提供参数

EventChannel 是 Flutter 监听宿主环境的 API ,FlutterEventChannel 是 iOS 宿主环境与 Flutter 交互平台通道的 API 。

Flutter 代码片段

const EventChannel eventChannel = const EventChannel('com.pages.flutter/call_flutter');
@override
void initState(){
  super.initState();
 eventChannel.receiveBroadcastStream(12345).listen(_onEvent,onError: _onError);
}

void _onEvent(Object event){
  setState(() {
    _content = event.toString();
  });
}

void _onError(Object error){
  setState(() {
    _content = error.toString();
  });
}

iOS 宿主环境代码片段

NSString *eventChannelName = @"com.pages.flutter/call_flutter";
FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:eventChannelName binaryMessenger:flutterViewController];
[eventChannel setStreamHandler:self];
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
    if (events) {
        events(@"hi flutter");
    }
    return nil;
}

- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
    return nil;
}

两端交互通信方式就是这样的,这里也只是介绍了他们通信的方式,具体如何优雅的封装、规范交互流程还需要我们自己去考虑下。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言程序设计

C语言程序设计

K. N. King / 吕秀锋、黄倩 / 人民邮电出版社 / 2010-4 / 79.00元

时至今日, C语言仍然是计算机领域的通用语言之一,但今天的 C语言已经和最初的时候大不相同了。本书最主要的一个目的就是通过一种“现代方法”来介绍 C语言,书中强调标准 C,强调软件工程,不再强调“手工优化”。这一版中紧密结合了 C99标准,并与 C89标准进行对照,补充了 C99中的最新特性。本书分为 C语言的基础特性、 C语言的高级特性、 C语言标准库和参考资料 4个部分。每章末尾都有一个“问与......一起来看看 《C语言程序设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具