闲鱼对 Flutter-Native 混合工程解耦的探索

1. 闲鱼Flutter现状

闲鱼是第一个使用Flutter混合开发的大型应用,但闲鱼客户端开发最深入体会的痛点就是编译时长影响开发体验。在Flutter+Native这种开发模式下,Native编译速度慢,模块开发无法突破。闲鱼集成了集团众多中间件,很多功能无法通过flutter直接调用,需使用各种channel到native去调用对应功能。总而言之,闲鱼目前Flutter开发面临如下几个痛点:

  • Flutter侧混合编译速度慢,Android首次编译10min+,iOS首次编译20min+
  • 混合栈编程中历史包袱导致IOS/Android双端返回给Flutter侧的数据可能存在不一致性
  • 集成模块开发效率相比模块开发较低,单模块页面测试性能数据无法展开;

2.解决方案一

2.1方案概述

此项目从立项至今已经很长一段时间,由于业务迭代快,native插件满天飞情况下,想要做到工程模块化拆分难度可想而知;如下图是项目立项为模块化拆分,业务方需要将各个业务拆分解耦合,拆分集团中间件,业务封装组件,Native业务代码,Flutter桥代码,Flutter组件库,Flutter侧业务代码等多个模块;项目初衷就是整理代码,提供一个Flutter可运行的干净环境,同时需要让flutter可以获取到native几乎所有能力,但是编译开发调试时候有想要速度快,效率高。能想到的最直接解决方案就是拆包,从0-1建立一个最小壳工程,然后拆分集团基本中间件,封装业务组件,Flutter插件等,如下是整个项目架构:

日常模块化单页面级需要使用最小壳工程,其内部又channel的声明和实现,通过运行最小壳工程运行得到结果,Flutter侧模块开发通过IOC调用到最小壳工程的channel得到返回结果,最后将模块化开发以一种pub或者git依赖方式集成到闲鱼FWN主工程即可;

2.2 阶段性产出

业务模块化拆分从来都是一种吃力不讨好的活,明知道拆出来有收益,但是投入产出比不足,因此历史包袱代码越来越厚重,以至于下一个接收的人都不敢轻易修改代码;在模块化拆分时候,开始项目时候提出过新起一个干净的工程,然后一步步拆分集团中间件,期间拆出了Mtop/Login/FlutterBoost/UI Plugin,耗时3周/2人,得到部分结果就是新业务,新界面开发满足基本快速迭代开发,缺点也很明显如下所示:

  • 拆分梳理Native的中间件繁琐,工作量巨大,最小化壳工程耗时3周/2人
  • 推动业务方拆分基础组件库更难,目前项目进展不顺
  • 维护成本高,拆分壳工程运行结果和主工程可能不一致
  • 业务迫切其结果,但投入产出比不足,比如Flutter单页面性能测试,Flutter侧模块化拆分,Fass工程一体基石

3.解决方案二

3.1 换位思考

(1)若自己是业务方,需要为Flutter侧去拆分包,去构建一个最小化壳工程,其成本是巨大的。 (2)Fass工程一体化依赖一个最小化壳工程的Native运行环境去运行Flutter侧代码,可是并非所有的业务方都会提供一个最小化壳工程去运行Fass,那么Fass工程一体化/模块开发如果在集团其他运行环境下进展? (3)最小化壳工程运行环境无法紧跟Native侧的各种版本,会导致运行结果不一致情况下也不敢随便使用;

如果解决此问题呢?个人提出过跨进程实现方式,在Android端侧跨进程调用实现方式一直很常见的场景,client访问server得结果,而Flutter侧和Native侧不就是client和server双端么?如下图所示,其实Flutter获取数据就是通过MethodChannel/EventChannel获取,因此可以换一种方式思考?

​3.2 IPC跨进程通信,Android Binder

期间在Android侧我使用过Android Binder去实现,新起一个APP做为壳工程,其内部实现了各种插件去访问主工程服务,获取结果然后返回给壳工程的Flutter调用,但是维护成本依然在;同时iOS侧没有对应的实现机制,因此此方式被抛弃;

3.3 具体方案:Hook代理+Socket服务

Android开发应该都熟悉hook和插件化技术,其实从之前的Flutter到Native的Chanel架构就可以想到一种思路,既然解决不了Native问题,那就解决Channel的问题吧,Native端侧的IPC方式无法实现,换到Flutter侧和Native侧的Channel通信侧去实现IPC吧。参考业务对于插件化hook机制/IPC机制的理解,结合自身对于flutter channel的理解,可以实现一种利用socket服务去hook method channel和event channel实现方式,去代理客户端的method channel和event channel,将处理结果通过socket交给服务端去处理拿到服务端真正的method channel和event channel数据即可,这才是我心中想要的实现方式就是如此,整个架构图如下:

客户端是一台手机,服务端也是一台手机,服务端跑闲鱼FWN主工程,客户端跑一个干净的Flutter工程;客户端先通过Flutter侧代码去找使用本端有对应的Channel,如果有则使用返回结果,如果没有则通过Socket请求结果到服务端主工程上,主工程根据Socket定义的协议字段去解析然后发起一个channel拿结果,之后通过socket将解决返回给客户端,客户端拿到了socket结果数据后执行想要的渲染方式即可;

或许你有质疑点:比如为什么要用2台手机,使用一台不可以么? 这里我推荐使用2台手机有如下2个原因: (1)一台手机运行2个APP,如果server在后台可能会导致进程资源被回收,Socket通信中断; (2)使用2台手机有一个极大好处是,你运行Android的Flutter侧Client代码,但是往往你需要验证Native侧双端Server代码数据,如果客户端手机/服务端手机是2台,只需要改下客户端的IP地址去请求Android手机的Server还是IOS手机的Server就可以验证结果;

3.4 尝试验证

比如如下的method channel代码如下:

Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {assert(method != null);final ByteData result = await binaryMessenger.send(name,codec.encodeMethodCall(MethodCall(method, arguments)),);if (result == null) {throw MissingPluginException('No implementation found for method $method on channel $name');}final T typedResult = codec.decodeEnvelope(result);return typedResult;}

修复result == null的场景,如果是我们指定的客户端,则通过socket去拿server数据,重点理解Fish MOD:START到Fish MOD:END代码思想就理解了;

Future<T> invokeMethod<T>(String method, [dynamic arguments]) async {assert(method != null);final ByteData result = await binaryMessenger.send(name,codec.encodeMethodCall(MethodCall(method, arguments)),);if (result == null) {//Fish MOD:START//throw MissingPluginException(//      'No implementation found for method $method on channel $name');//socket从服务端手机获取值final dynamic serverData =await SocketClient.methodDataForClient(clientParams);//Fish MOD:END}final T typedResult = codec.decodeEnvelope(result);return typedResult;}

最后通过此中方式验证了MethodChannel/EventChannel数据正常收发的可行性,后续还需要在业务场景具体实验耕田;

4.结果对比和展望

结果对比:

无法方案1和方案2最终都可以解决编译运行时长的问题,但方案1在拆分模块和维护模块时候都有很高的成本,运行时长虽然降低了,但是模块化工作量却加大很多,方案2可以完美解决拆分成本和维护成本,但是不足之处就是运行环境苛刻,可操作性不足,其需要2部手机作为运行环境,另针对于一些页面跳转逻辑,可能客户端手机A触发到服务端手机B上,操作性不在同一台手机上;当然方案二虽然有一定缺陷,却可以解决很多问题,因此后续在闲鱼模块化拆分落地项目中,在思考是否有更加完美的解决方法。

作者:祈晴

原文链接

本文为阿里云原创内容,未经允许不得转载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法通关第二十关-青铜挑战认识图结构

大家好我是苏麟 , 今天来聊聊图结构 . 我们平时在工作、学习中会大量使用图结构&#xff0c;不过呢在使用代码进行具体实现的时候极少使用图&#xff0c;主要是图里容易产生环&#xff0c;难以处理。 在算法里&#xff0c;考察图也不是很多&#xff0c;主要是图的表示非常复杂&…

我的前端成长之路:中医药大学毕业的业务女前端修炼之路

大家好&#xff0c;我是风月&#xff0c;2014年二进宫进入阿里&#xff0c;目前是业务平台体验技术数据服务前端团队负责人&#xff0c;负责 BizCharts 横向建设以及财鲸数据业务支撑。本次分享我将回顾作为业务前端从前端工程转型到数据可视化过程中的心路历程。 前端工程师的…

过去5年,PolarDB云原生数据库是如何进行性能优化的?

云数据库实现计算存储分离&#xff0c;支持计算与存储的独立扩展&#xff0c;其用户还可以享受按量付费等特性。这使得基于云数据库的系统更加高效、灵活。因此&#xff0c;构建并使用云原生数据库的势头愈演愈烈。另一方面&#xff0c;云化存储服务已经是云的标准能力&#xf…

ChatGPT 玩「脱」了,写了份毁灭人类计划书,还遭到了 Stack Overflow 的封杀.........

【CSDN 编者按】OpenAI 的新通用聊天机器人原型 ChatGPT 可谓是风靡一时&#xff0c;但却突遭 StackOverflow 封禁。整理 | 刘春霖 责编 | 张红月出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;在上周发布的《挑战 Google 搜索&#xff1f;OpenAI 发布最强 …

基于任务调度的企业级分布式批处理方案

背景 先来谈下什么是分布式批处理&#xff0c;从字面来理解就是有大批量的业务数据需要应用程序去批量计算处理&#xff0c;而通过单机模式去执行会耗费很长的处理时间&#xff0c;也不能充分发挥业务集群中每个应用节点处理能力。通过一些常见的分布式批处理方案&#xff0c;…

如何用一个插件解决 Serverless 灰度发布难题?

导读本文适合&#xff1a;想了解 Serverless 灰度发布的同学。认为当前 Serverless 灰度发布配置太复杂&#xff0c;寻求简洁版灰度发布流程的同学。想了解 Serverless Devs 组件和插件之间关系的同学。Serverless 灰度发布 什么是 Serverless ? Serverless 顾名思义就是无服…

阿里云云原生一体化数仓 — 分析服务一体化新能力解读

分析服务一体化一直都是阿里云离线实时一体化数仓的重要能力创新 分析服务一体化需求分析 业务在线化、运营精细化驱动数据实时化 随着互联网的信息&#xff0c;业务对于在线化、运营精细化的需求日益强烈&#xff0c;领导驾驶舱、实时大屏等&#xff0c;起到了越来越重要的…

Fortinet谢青:有信心在未来几年跻身SD-WAN市场份额首位

自创立以来&#xff0c;Fortinet始终引领网络和安全行业的融合创新发展&#xff0c;跻身变革前沿20余载。作为创始人、董事会主席兼首席执行官&#xff0c;谢青专门就目前行业的关键发展趋势、业务发展动向以及 Fortinet 如何帮助广大用户实现可持续发展目标畅谈了其观点和看法…

一位 sealer maintainer 的心路历程

引言 在 2021 年四月左右&#xff0c;我有幸在 sealer 启动初期了解到其相关工作&#xff0c;并且不久后就作为初始的几位开发同学之一&#xff0c;加入到了 sealer 的开发工作中。 本文&#xff0c;我将回顾个人参与 sealer 开源项目的机缘巧合&#xff0c;参与过程中的挑战…

龙蜥社区开源 coolbpf,BPF 程序开发效率提升百倍

引言 BPF 是一个新的动态跟踪技术&#xff0c;目前这项技术正在深刻的影响着我们的生产和生活。BPF 在四大应用场景发挥着巨大作用&#xff1a; 系统故障诊断&#xff1a;它可以动态插桩透视内核。网络性能优化&#xff1a;它可以对接收和发送的网络包做修改和转发。系统安全…

线上故障突突突?如何紧急诊断、排查与恢复

概述 稳定性大于一切&#xff0c;因此我们需要有更有效的方式避免线上故障。在发生故障不可避免的假设下&#xff0c;我们需要能够快速修复&#xff0c;减少线上影响。基于以上这些想法&#xff0c;我们提出了 1-5-10 的快恢目标&#xff0c;所谓 1-5-10 的目标就是是要我们对…

巧用 API 网关构建大型应用体系架构

近期阿里云重磅发布了BizWorks一体化的云原生应用的开发和运营平台&#xff0c;内置阿里巴巴业务中台构建的最佳技术实践。BizWorks提供的产品能力&#xff0c;普遍适用于企业云原生应用高效开发以及企业业务能力沉淀和复用的场景。BizWorks提供业务架构师一整套的可视化业务建…

可观测|时序数据降采样在 Prometheus 实践复盘

基于 Prometheus 的监控实践中&#xff0c;尤其是在规模较大时&#xff0c;时序数据的存储与查询是其中非常关键&#xff0c;而且问题点较多的一环。如何应对大数据量下的长周期查询&#xff0c;原生的 Prometheus 体系并未能给出一个令人满意的答案。对此&#xff0c;ARMS Pro…

倒计时1天!中国移动算力网络创新成果即将发布!

数字时代&#xff0c;随着计算机技术的普及&#xff0c;电脑及相关电子产品日新月异&#xff0c;给人们日常生活带来了翻天覆地的变化。多样化的电脑功能提高了各项事务协同管理的便捷性&#xff0c;电脑游戏也极大地丰富了人们的娱乐生活。未来电脑又会使人们的办公模式、娱乐…

托管式服务网络:云原生时代的应用体系架构进化

背景 回顾下应用服务架构体系的演进。从服务调用方与提供方的处理方式来看, 可以分为 3 个阶段。 第一个阶段是集中式负载均衡, 也就是说服务调用方是通过一个外部的负载均衡路由到对应的服务提供方。其优势显而易见, 对应用本身无侵入, 可以支持多语言多框架来开发实现应用本…

深度|为什么一定要从DevOps走向BizDevOps?

数字经济时代&#xff0c;数字化转型成为社会的普遍共识和行动。越来越多的业务运行在数字化基座之上&#xff0c;软件系统正成为业务创新的价值核心和创新引擎。在这一趋势下&#xff0c;软件产业面临着许多新挑战和新机遇&#xff1a;一方面&#xff0c;万物互联下软件系统规…

科普达人丨一文看懂阿里云的秘密武器“神龙架构”

在一台电脑中&#xff0c;我们把CPU和硬盘比作一家公司的加工厂和仓库&#xff0c;那么两个部门的任务就是处理数据和存储数据。 但是因为土地价格和劳动力价格差异较大等因素&#xff0c;需要将两个部门分别建在不同的地方&#xff0c;这也就是在云上的情况&#xff0c;也就是…

卓越工程实践之—前端高质量单测

高单测等于高质量&#xff1f; 笔者负责的npm包是 ICBU信天翁低代码平台渲染引擎&#xff0c;160应用 600页面基于该引擎开发&#xff0c;内网日npm下载 1K。经过不懈努力&#xff08;CV&#xff09;&#xff0c;终于把单测提到了95%。 然而&#xff0c;虽然在覆盖率上获得了…

中国移动云电脑重磅发布,又一场革命到来!

12 月 11 日&#xff0c;2022 中国移动全球合作伙伴大会产业链创新暨算力网络分论坛顺利举办。会上&#xff0c;中国移动基于算力网络战略下的扛鼎力作——中国移动云电脑重磅发布&#xff01;中国移动云能力中心总经理方力表示&#xff1a;“它将会成为中国移动算力网络对外输…

PolarDB-X 如何做分布式数据库热点分析

背景 PolarDB-X是一款计算存储分离的分布式数据库&#xff0c;分布式的处理能力是PolarDB-X的核心特性之一&#xff0c;单个数据库实例的多个计算节点会均摊全部的SQL流量&#xff0c;这样就可以通过节点的扩缩容来快速满足不同的流量峰值场景。 在PolarDB-X 1.0时代&#xff…