背景及综述
Flutter 在目前跨平台方案中有更好的平台一致性以及更优的体验。但对于本身已有成熟的业务代码的项目来说,更多的是采用混合栈的方式,在不变更原有 App 业务的基础上,将 Flutter 能力扩展为子模块进行接入和开发。这样并不影响原有的业务和原生能力,又可以结合业务需求进行技术选择。
混合导航栈
混合导航栈,指的是在混合开发中原生页面和Flutter页面相互掺杂,存在于用户视角的页面导航栈视图。在混合开发的应用中,原生Android、iOS与Flutter各自实现了一套互不相同的页面映射机制,原生平台采用的是单容器单页面,即一个ViewController或Activity对应一个原生页面;而Flutter采用单容器多页面的机制,即一个ViewController或Activity对应多个Flutter页面。Flutter在原生的导航栈之上又自建了一套Flutter导航栈,这使得原生页面与Flutter页面与之间进行页面切换时,需要处理跨引擎的页面切换问题。
原生页面跳转Flutter页面
从原生页面跳转至 Flutter 页面,实现起来比较简单。因为 Flutter 本身依托于原生提供的容器,即iOS 使用的是FlutterViewController,Android 使用的是Activity 中的 FlutterView。所以我们通过初始化 Flutter 容器,为其设置初始路由页面之后,就可以以原生的方式跳转至 Flutter 页面了。
对于iOS混合工程来说,可以先初始化一个FlutterViewController实例,然后设置初始化页面路由,将其加入原生的视图导航栈中即可完成跳转,如下所示。
//iOS 跳转至Flutter页面
FlutterViewController *vc = [[FlutterViewController alloc] init];
//设置Flutter初始化路由页面
[vc setInitialRoute:@"defaultPage"];
//完成页面跳转
[self.navigationController pushViewController:vc animated:YES];
Flutter页面跳转至原生页面
相比原生页面跳转Flutter页面,从Flutter页面跳转至原生页面则会相对麻烦些。因为我们需要考虑以下两种场景,即从Flutter页面打开新的原生页面和从Flutter页面回退到旧的原生页面。
注意问题
需要注意的是,与纯 Flutter 应用不同,原生应用混编 Flutter 由于涉及到原生页面与 Flutter 页面之间切换,因此导航栈内可能会出现多个 Flutter 容器的情况,即多个 Flutter 实例。Flutter 实例的初始化成本非常高昂,每启动一个 Flutter 实例,就会创建一套新的渲染机制,即 Flutter Engine,以及底层的 Isolate。而这些实例之间的内存是不互相共享的,会带来较大的系统资源消耗。