Flutter 混合开发 (交互通信)

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

内容简介:上篇我们介绍了 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;
}

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


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

查看所有标签

猜你喜欢:

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

解构产品经理:互联网产品策划入门宝典

解构产品经理:互联网产品策划入门宝典

电子工业出版社 / 2018-1 / 65

《解构产品经理:互联网产品策划入门宝典》以作者丰富的职业背景及著名互联网公司的工作经验为基础,从基本概念、方法论和工具的解构入手,配合大量正面或负面的案例,完整、详细、生动地讲述了一个互联网产品经理入门所需的基础知识。同时,在此基础上,将这些知识拓展出互联网产品策划的领域,融入日常工作生活中,以求职、沟通等场景为例,引导读者将知识升华为思维方式。 《解构产品经理:互联网产品策划入门宝典》适合......一起来看看 《解构产品经理:互联网产品策划入门宝典》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具