Mobile Development 11 min read

Hybrid Stack Management in Flutter

The article explains how to manage a hybrid Flutter‑Native stack by using a single shared Flutter engine instance linked to native view controllers, unified openUrl routing, native‑driven page transitions, resource‑efficient reuse of native components, and detailed guidance on creating and publishing Flutter plugins and packages.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Hybrid Stack Management in Flutter

This article is the second part of a series focusing on enabling Flutter to develop and meet business requirements. It covers hybrid stack management, including mixed stack management, capability alignment in mixed environments, and package management.

混合栈的管理

Introducing Flutter introduces the challenge of managing the mixed stack. For example, a common scenario involves navigating from the homepage to a product detail page, then to a guess-you-like page, session page, and back to the detail page. The solution must address how to handle Native and Flutter any nesting.

解决方案应具有以下特点:

a.每个页面都有一个VC(Activity),确保基于VC(Activity)生命周期的逻辑(如埋点)正常工作

b.不同Flutter页面之间可以正常通信,共享数据

c.Native可以调起任意的Flutter页面,无论是首次打开还是之后

d.资源占用尽可能少,性能尽可能好

e.用户体验要同之前无差异

为了解决这些问题,设计如下:

a.所有Flutter页面公用一个Flutter实例(FlutterViewController for iOS&FlutterNativeView for Android)

iOS通过addChildViewController和removeFromParentViewController直接在FlutterViewController层面复用

Android由于activity不能add/remove,因此抽取并复用了FlutterNativeView(相对应的FlutterView也是单例),在不同的Activity上复用

这种Flutter单例的实现带来的好处显而易见。一方面,单个Flutter实例因为位于相同的Isolate,其数据通信和共享将很容易。另一方面,引擎的默认实现中,每一个Flutter实例会新启动三个线程(IO,GPU和UI),带来了额外的资源使用,单实例可以避免这个问题

b.每一个Flutter页面不仅是一个FlutterPage,也有一个对应的NativeVC(或Activity)与之相对应

通过唯一的id将其关联,可以方便地使Flutter/Native页面保持同步

c.Native和Flutter都基于openUrl来管理页面跳转

统一的路由机制可以统一管理所有页面跳转相关逻辑,对业务侧提供标准一致的服务

d.所有的页面跳转和动画都通过Native实现

因为原生(iOS/Android)自带跳转动画,而Flutter内部跳转也自带动画,为了用户体验,禁止Flutter内部跳转(push/pop)相关动画,统一由Native接管,这样用户就感受不到差异

e.使用一个空白Widget作为RootWidget

以便保证Flutter页面完整退出时(如回到首页),可以释放所有的Flutter详情页等资源

架构图如下:

待优化部分

1.目前为了保证页面跳转时的正常显示,前一个页面是截图,后一个页面是真正的Flutter页面,也就是说每一个FlutterWrapperVC(Activity)都保留了一张截图,带来了额外的内存消耗

复用Native组件

当前闲鱼Flutter业务全页面采用Flutter实现,但也有一些Native组件的复用

通过Channel调用部分中间件

如埋点,网络请求与解析等只能调用已有的二方中间件,这种情况下基于Platform Channels去调用

使用Dart重写部分中间件

对于一些有标准协议支持(如http)的中间件,如阿里云提供的基于http的文件上传服务,可以通过dart重写的方式去实现

通过新Window方式,盖上已有的Native组件

如下图所示的浮层和键盘上的输入框,均为直接复用Native组件

视频的实现

Flutter引擎通过Texture的方式,由Native侧提供相应的渲染内容(解码视频文件获得帧Buffer等)的方式来提供对于视频的支持

Flutter的渲染流程略图

iOS上Flutter视频渲染逻辑:

Android上Flutter视频渲染逻辑:

包管理

构建和发布插件(包)

1.使用下面命令创建插件:

flutter create --template=plugin hybrid_stack_manager

2.开发插件并在example中测试通过 3.完善README.md, CHANGELOG.md,pubspec.yaml,podspec.json,LICENSE等相关文件 4.使用命令验证并发布

cd root/path/to/your/flutter/package
pub publish

如果出现一个连接需要验证身份,拷贝到浏览器访问即可

我们可以将实现的插件(如网络请求,混合栈管理等)包,Dart包(阿里云上传组件等),以多种形式引入。下面以上文中的混合栈管理插件hybrid stack manager为例说明下各种包管理方式:

包名+版本

实现后可发布到https://pub.dartlang.org,再在pubspec.yaml中基于名称+版本号引入

此部分包下载后路径位于:~/.pub-cache/hosted/pub.dartlang.org/hybrid stack manager-0.0.2

包名+git信息

也可以将代码包上传到可访问到的git地址,通过git地址+ref的方式引入

此部分包下载后路径位于:~/.pub-cache/git/hybrid stack manager-d9f6bdf169683fd8642168ec37c5820940ed344a

包名+路径

也可以将代码放在某一文件夹(建议当前Flutter工程根目录之下),通过路径引入

写在后面

本文着重介绍了混合场景下如何去做业务研发。解决这一问题后,接下来就要解决实际业务开发中遇到的各种兼容性/稳定性问题,这些敬请关注本系列的上线篇。

联系我们

如果对文本的内容有疑问或指正,欢迎告知我们。

闲鱼技术团队是一只短小精悍的工程技术团队。我们不仅关注于业务问题的有效解决,同时我们在推动打破技术栈分工限制(android/iOS/Html5/Server 编程模型和语言的统一)、计算机视觉技术在移动终端上的前沿实践工作。作为闲鱼技术团队的软件工程师,您有机会去展示您所有的才能和勇气,在整个产品的演进和用户问题解决中证明技术发展是改变生活方式的动力。

简历投递: [email protected]

识别二维码,前瞻技术尽在掌握

Fluttermobile developmenthybrid-developmentNative IntegrationFlutter ArchitectureFlutter Best PracticesFlutter FrameworkFlutter PerformanceFlutter PluginFlutter Tutorial
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.