阿里巴巴闲鱼全面应用的新一代混合技术方案 FlutterBoost
1重构计划
在闲鱼推进Flutter化过程当中,更加复杂的页面场景逐渐暴露了老方案的局限性和一些问题。所以我们启动了代号FlutterBoost(向C++ Boost库致敬)的新混合技术方案。这次新的混合方案我们的主要目标有:
-
可复用通用型混合方案
-
支持更加复杂的混合模式,比如支持主页Tab这种情况
-
无侵入性方案:不再依赖修改Flutter的方案
-
支持通用页面生命周期
-
统一明确的设计概念
跟老方案类似,新的方案还是采用共享引擎的模式实现。主要思路是由Native容器Container通过消息驱动Flutter页面容器Container,从而达到Native Container与Flutter Container的同步目的。我们希望做到Flutter渲染的内容是由Naitve容器去驱动的。
简单的理解,我们想做到把Flutter容器做成浏览器的感觉。填写一个页面地址,然后由容器去管理页面的绘制。在Native侧我们只需要关心如果初始化容器,然后设置容器对应的页面标志即可。
2主要概念
3 Native层概念
-
Container:Native容器,平台Controller,Activity,ViewController
-
Container Manager:容器的管理者
-
Adaptor:Flutter是适配层
-
Messaging:基于Channel的消息通信
4 Dart层概念
-
Container:Flutter用来容纳Widget的容器,具体实现为Navigator的派生类-
-
Container Manager:Flutter容器的管理,提供show,remove等Api
-
Coordinator: 协调器,接受Messaging消息,负责调用Container Manager的状态管理。
-
Messaging:基于Channel的消息通信
5 关于页面的理解
在Native和Flutter表示页面的对象和概念是不一致的。在Native,我们对于页面的概念一般是ViewController,Activity。而对于Flutter我们对于页面的概念是Widget。我们希望可统一页面的概念,或者说弱化抽象掉Flutter本身的Widget对应的页面概念。换句话说,当一个Native的页面容器存在的时候,FlutteBoost保证一定会有一个Widget作为容器的内容。所以我们在理解和进行路由操作的时候都应该以Native的容器为准,Flutter Widget依赖于Native页面容器的状态。
那么在FlutterBoost的概念里说到页面的时候,我们指的是Native容器和它所附属的Widget。所有页面路由操作,打开或者关闭页面,实际上都是对Native页面容器的直接操作。无论路由请求来自何方,最终都会转发给Native去实现路由操作。这也是接入FlutterBoost的时候需要实现Platform协议的原因。
另一方面,我们无法控制业务代码通过Flutter本身的Navigator去push新的Widget。对于业务不通过FlutterBoost而直接使用Navigator操作Widget的情况,包括Dialog这种非全屏Widget,我们建议是业务自己负责管理其状态。这种类型Widget不属于FlutterBoost所定义的页面概念。
理解这里的页面概念,对于理解和使用FlutterBoost至关重要。
6 与老方案主要差别
前面我们提到老方案在Dart层维护单个Navigator栈结构用于Widget的切换。而新的方案则是在Dart侧引入了Container的概念,不再用栈的结构去维护现有的页面,而是通过扁平化key-value映射的形式去维护当前所有的页面,每个页面拥有一个唯一的id。这种结构很自然的支持了页面的查找和切换,不再受制于栈顶操作的问题,之前的一些由于pop导致的问题迎刃而解。也不需要依赖修改Flutter源码的形式去进行页面栈操作,去掉了实现的侵入性。
实际上我们引入的Container就是Navigator的,也就是说一个Native的容器对应了一个Navigator。那这是如何做到的呢?
7 多Navigator的实现
Flutter在底层提供了让你自定义Navigator的接口,我们自己实现了一个管理多个Navigator的对象。当前最多只会有一个可见的Flutter Navigator,这个Navigator所包含的页面也就是我们当前可见容器所对应的页面。
Native容器与Flutter容器(Navigator)是一一对应的,生命周期也是同步的。当一个Native容器被创建的时候,Flutter的一个容器也被创建,它们通过相同的id关联起来。当Native的容器被销毁的时候,Flutter的容器也被销毁。Flutter容器的状态是跟随Native容器,这也就是我们说的Native驱动。由Manager统一管理切换当前在屏幕上展示的容器。
我们用一个简单的例子描述一个新页面创建的过程:
-
创建Native容器(iOS ViewController,Android Activity or Fragment)。
-
Native容器通过消息机制通知Flutter Coordinator新的容器被创建。
-
Flutter Container Manager进而得到通知,负责创建出对应的Flutter容器,并且在其中装载对应的Widget页面。
-
当Native容器展示到屏幕上时,容器发消息给Flutter Coordinator通知要展示页面的id.
-
Flutter Container Manager找到对应id的Flutter Container并将其设置为前台可见容器。
这就是一个新页面创建的主要逻辑,销毁和进入后台等操作也类似有Native容器事件去进行驱动。
总结
目前FlutterBoost已经在生产环境支撑着在闲鱼客户端中所有的基于Flutter开发业务,为更加负复杂的混合场景提供了支持,稳定为亿级用户提供服务。
网友评论