引言
Flutter是Google开源的UI工具包,帮助开发者通过一套代码库高效构建多平台应用,支持移动、Web、桌面和嵌入式平台。Flutter技术已经成为越来越多行业伙伴重点投入的技术建设方向,国内各大厂也都建设了自己的Flutter工程化体系并服务各自的业务场景。Flutter技术带来的收益:
从2020年开始,震坤行移动团队面临如下挑战:
经过移动团队的技术调研,我们决定全面拥抱Flutter,提升移动端的研发效能。
App全面转向Flutter的成本和风险较高,目前稳健的做法都是Native渐进式向Flutter迁移,根据业务和技术需求保持Native和Flutter混合并存。本文主要介绍项目中Flutter-Native混合开发相关实践中Flutter和原生之间的交互:页面跳转、数据处理等。
混合技术方案选型
FlutterBoost是一个Flutter插件,它的理念是将Flutter像Webview那样来使用,可以轻松地为现有原生 应用程序提供Flutter混合集成方案。FlutterBoost采用共享引擎的实现方式,主要思路是由 Native容器Container 通过消息驱动 Flutter⻚面容器Container,从而达到 Native Container 与 Flutter Container的同步目的。Flutter渲染的内容是由Native容器去渠道的。FlutterBoost帮助处理⻚面的映射和跳转, 开发者只需关心⻚面的名字和参数即可(通常可以是URL)。它具有以下优点:
全局Router构建
在Native和Flutter混合开发项目中,首先我们需要解决的就是利用FlutterBoost构建一个全局Router,统一管理Native和Native、Native和Flutter,Flutter和Flutter之间的⻚面跳转。
在Flutter Module中完成新⻚面的开发,需要在 main.dart中定义相关路由,代码如下:
原生如何打开Flutter页面(Activity或者Fragment形式):通过BoostFlutterActivity和FlutterFragment来将Flutter页面打开。
具体实现:定义FlutterRouter类用来打开Flutter Activity和Fragment,其中 flutterRouter map对应main.dart中定义的所有路由,即flutterRouter map包含的路由通过FlutterBoost调用。在后面我们会将openPageByUrl添加原生路由的处理。
在Flutter模块中页面跳转不使用Flutter原生提供的 Navigator实现跳转,而采用FlutterBoost来统一处理。FlutterBoost打开页面的方法为
FlutterBoost.singleton.open,该方法会调用plugin中的openPage方法,而openPage最终调用到Native层中FlutterBoost初始化所定义的INativeRouter
在INativeRouter实现中将路由处理也交给之前定义的FlutterRouter,完善openPageByUrl方法来统一处理所有路由,那么最终FlutterRouter可以用来处理所有Native和Flutter路由。
上述代码中Native路由的处理针对某些路由进行了特殊处理,目的是为了兼容以前的代码。
全局Router参数处理
在路由跳转过程中,我们还需要关注如何传递和接收参数。参数主要包括基本类型、List数据、对象数据,下面分别介绍各种数据类型如何处理。
1. Native -> Flutter
从Native端参数会放入到SerializableMap中,然后传递给Flutter。在Flutter模块我们可以直接获得基本类型等,对象数据通过json传递获得
2. Flutter -> Native
如果是简单的Map参数的话,会直接通过 FlutterRouter 中ARouter处理而不需要特殊处理。如果传递是对象的话会涉及到json转换,在我们项目中是为了保持原来业务代码而使用到对象数据的传递,但是建议后续参数全部采用Map形式传递,可以保证 FlutterRouter处理的统一性。
startActivityForResult处理
在Android中我们经常遇到这种场景:启动另一个Activity并接受返回的结果。那么在跨Module中怎么处理这种情况呢?
1. Native⻚面打开Flutter⻚面并获取返回数据
FlutterBoost通过
FlutterBoost.singleton.closeCurrent(result: result, exts: exts); 方法来关闭页面,该方法会调用FlutterBoostPlugin中的closePage方法。
最终result 不为空就会调用setResult方法返回结果。其中对应result的key是RESULT_KEY = "_flutter_result_";
所以对于startActivityForResult启动的Flutter页面,只需要将返回值放入result map中即可
2. Flutter⻚面打开Native⻚面并获取返回数据
在Flutter中可以直接获取到打开⻚面之后的返回值,这里我们只需要关注返回值map中具体的key-value。
在FlutterBoost中Flutter页面是通过BoostFlutterActivity呈现,追踪源码可以看到最终返回值Map中requestCode和resultCode对应的key为_requestCode__和_resultCode__
MethodChannel交互
Flutter平台特定的API支持不依赖于代码生成,而是依赖于灵活的消息传递的方式:
在FlutterBoost初始化的时候,可以在BoostLifecycleListener中创建MethodChannel来提供与客户端通信的渠道
在FlutterBoost中创建MethodChannel
总结:
本文主要介绍了Flutter混合开发过程中Native与Flutter之间的交互,包括⻚面调用、参数传递、数据交换。在混合开发过程中,我们实现了全局Router在不同Module可以保持一致性处理,并介绍了⻚面跳转过程中参数的处理和回调、MethodChannel交互。
在实施Flutter混合开发落地之后,主要体验如下:
作者简介
李亮,震坤行移动端高级研发工程师, 2019年加入震坤行。
来源-微信公众号:产品技术团队
出处
:https://mp.weixin.qq.com/s/FzJkLufrADkGQQQVG6mhOw