找回密码
 会员注册
查看: 29|回复: 0

开源|Fair在58同城拍客App中的实践

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64113
发表于 2024-9-20 00:03:06 | 显示全部楼层 |阅读模式
FFair2.0专题● 项目名称:Fair2.0● Github地址:https://github.com/wuba/fair● 项目简介:Fair是为Flutter设计的动态化框架,可以通过FairCompiler工具对Dart源文件的转化,使项目获得动态更新Widget的能力。Fair2.0是为了解决Fair1.0版本的“逻辑动态化”能力不足。本文旨在为大家提供Fair在实际项目中落地的完整案例,包含了使用Fair进行动态页面改造、复杂场景使用、接入过程中遇到的问题、Fair接入前后的性能对比、热更新方案设计等等内容。本文重在介绍Fair的落地,不会涉及过多的技术原理,如果对Fair原理感兴趣的同学,可以阅读以下文章:《Fair逻辑动态化架构设计与实现》《Fair逻辑动态化通信实现》《Fair下发产物-布局DSL生成原理》《Fair逻辑语法糖设计与实现》《Fair热更新设计与实现》00本文目录01Fair接入和使用流程1.1接入Fair对于Fair的接入方式,推荐大家使用 源码依赖 的方式,下载地址如下:gitclonehttps://github.com/wuba/fair.git在pubspec.yaml文件里添加依赖:假如Fair源码和你的项目代码在同一个目录下另外需要特别注意的是,Fair内部通过fair_version库来做版本控制,所以大家需要根据自己本机的FlutterSDK版本来决定fair_version的版本。以我的电脑为例子,我本地使用的FlutterSDK版本为2.5.0,所以我强制指定fair_version的版本为flutter_2_5_0:1.2将Widget改造为可动态下发的bundle将一个Widget改造为可以动态下发的bundle需要三步。第一步:改造main函数需要去掉默认的runApp(MyApp()),然后手动调用一下WidgetsFlutterBinding.ensureInitialized(),最后用FairApp来包裹项目的根Widget。第二步:添加 @FairPatch() 注解在需要改造的Widget上添加 @FairPatch() 注解。第三步:执行build_runner命令执行了 build_runner 即可生成 bundle 资源flutterpubrunbuild_runnerbuild1.3bundle资源生成位置和组成bundle资源的位置,位于:project->build->fair下。一个bundle资源包含了两个文件:一个是js文件,一个是json文件。js文件里面包含的是动态页面的逻辑部分json文件包含的是动态页面的布局DSL1.4使用FairWidget加载bundle资源bundle资源生成好以后,我们可以使用FairWidget组件对其进行加载。在本地测试时,我们可以将bundle资源拷贝到assets目录下,然后将assets资源的地址通过path参数传递给FairWidget:运行效果如下:本地测试通过以后,可以将bundle资源托管到自己的服务器上,然后将path换成一个bundle资源的服务器下载地址即可:使用小结到这里简单小结一下Fair的使用步骤:对于一个简单的页面可以通过以上步骤进行改造,但是实际的项目中,情况往往比较复杂,所以,我们下面继续介绍在一些复杂的业务场景下,如何使用Fair。1.5动态页面之间的参数传递Fair提供了两个注解,可以实现动态页面之间的参数传递:@FairWell@FairProps这两个注解的区别是:@FairWell注解传递的参数不能参与逻辑运算,而@FairProps传递的参数可以参与逻辑运算。@FairWell支持Dart语言的所有数据类型,而@FairProps只支持传递一个Map。来看看示例代码。@FairWell的使用:@FairProps的使用:1.6动态页面之间的跳转推荐使用 命名路由 的方式进行跳转。首先注册路由表:然后使用Navigator.pushNamed进行跳转:1.7动态页面引用本地Widget组件:@FairBinding对于一个本地的Widget,如果直接在动态页面里面引用的话,Fair无法完成DSL的生成,需要使用 @FairBinding注解来对本地Widget组件进行标记。标记完成后,可以运行flutterpubrunbuild_runnerbuild命令,运行成功后,会在项目的src目录下,生成本地Widget的组件映射表:AppGeneratedModule。我们需要对AppGeneratedModule进行注册:然后就可以在动态页面里使用了:1.8动态页面引用三方sdk的Widget组件:@FairBinding(package)那很多人可能会有疑问了,假如我引用的是一个第三方SDK里的Widget呢?我们依然使用的是 @FairBinding注解,不过需要我们将三方SDK的Widget的package路径传递给FairBinding:1.9逻辑模版使用:FairDelegate对于页面中一些固定的逻辑方法,我们可以将其抽离出来,放到FairDelegate里面,来降低Dart与JS的频繁通信,达到提升性能的目标。甚至一些页面,只需要UI动态化,而不需要逻辑动态化,那么完全可以使用FairDelegate来实现。使用FairDelegate方式很简单,首先自定义一个类,让它继承FairDelegate:然后,需要在FairApp里注册模板:1.10使用IFairPlugin桥接常用第三方SDK的能力我们在动态页面中,经常会用到一些第三方SDK,比如网络请求、权限申请、拍照功能等等。此时,我们需要使用IFairPlugin来桥接第三方SDK的能力,才能在动态页面中正常使用。我们以权限申请库为例子。首先,自定义一个类,继承IFairPlugin:重写getRegisterMethods(),在里面注册需要暴露给JS侧的方法。同样的,定义好Plugin后,需要在FairApp里进行注册:然后就可以正常使用了。02Fair在58拍客中的落地Fair上线后,我们也是在58拍客里进行了接入和使用。我们完成了三个页面的改造:发布页面、视频列表页面、视频页面。并且自己设计了热更新流程,下面,我们就来详细介绍一下。2.158拍客接入Fair前后UI对比接入Fair前的页面:接入Fair后的页面:Fair能做到像素级别的还原,因此接入前后,页面几乎看不出任何差异。2.2更新方案设计因为目前Fair的热更新平台正在开发中,还没有上线,因此,我们自己设计了一套热更新方案:方案1:同步更新方案2:静默更新方案3:预加载+同步更新方案4:预加载+静默更新2.2.1同步更新方案采用同步更新方案时,每次进入页面会先请求版本号,如果有更新,则下载bundle资源(如已有缓存则不下载),最后展示。流程图如下:2.2.2静默更新方案采用静默更新方案,每次进入页面时,如有缓存则直接展示,并异步更新bundle资源。如无缓存,则使用同步更新。所以,静默更新有3个特点:2.2.3预加载对于标记为预加载的资源,我们会在APP启动的时候就下载好bundle资源。比如,我们改造58拍客的视频列表页,它位于首页的第二个tab,对于这样的tab页,我们当然是希望它在APP启动时就进行预加载。预加载的方案一般不会单独使用,会选择与同步更新和静默更新一起使用。总结2.3如何保证bundle资源安全性?如果我们在下载bundle资源的过程中,因为一些未知原因导致资源未下载完整,或者说下载了一个被恶意替换的资源,此时,去加载这样一个不合法资源的话,会发生一些未知的错误,增加APP的风险。那么如何解决呢?我们的解决方案是采用验证 校验和 的方式。我们将bundle资源上传到服务器时,会通过MD5或SHA-256计算出bundle资源的 校验和(Checksum),并由热更新接口下发。客户端完成bundle下载后,重新计算一遍得出校验和,如果与服务端下发一致,则为完整且合法的,可以执行加载。特别注意:上图中展示的校验和是明文的形式,实际开发中,需要大家对其进行加密后再下发。这样做是为了进一步提升数据的安全性。比如拍客里面,是对其进行了非对称加密后下发,客户端解密后再使用。2.4兜底策略(防止未知错误)在拍客里,我们加入了一个兜底的策略,即:由Server端控制加载bundle资源还是Flutter原生的Widget。伪代码如下:这样做的目的是,当线上发生一些未知的错误而无法纠正时,能够及时控制。2.5Fair落地过程中遇到的问题第一个问题:图片模糊如上图所示,我们在完成改造后,加载页面发现图片变得非常模糊。之所以会有这个问题是因为,Fair将DSL转化为Widget时,默认取的是assets目录下的1x图,所以导致了在一些高分辨率手机下出现模糊。解决方案是,1x图不要使用低分辨率图片,且Image需要设置width、height和fit属性。第二个问题是:colors属性缺失我们在代码里设置了一个颜色值:Colors.red[50]:但是生成bundle资源后,发现DSL里并没有对于的color属性:出现这个问题的原因是,Fair暂时不能支持解析Colors.xx[xx] 这种设置颜色的深度的语法。推荐使用十六进制颜色值Color(0xAARRGGBB)的写法。03接入Fair前后性能对比首先同步一下开发环境和测试环境:开发环境:macOSBigSur11.2(AppleM1)FlutterSDK2.5.0测试设备:HUAWEInova7,Android11iOSiPhoneXSMax,iOS13.3测试方式:非压测,模拟用户正常使用模拟了12个事件测试页面:3.1页面流畅度通过模拟12个操作事件,如滑动、点击、跳转来进行测试。3.2内存表现(增量数据)接入Fair后,Android端的内存占用 增加了22MB,iOS端增加了17.9MB。3.3启动时间(增量数据)接入Fair后,Android端的启动时间 增加了 0.03秒,iOS端增加了0.1秒。04Fair开发体验总结我们在58拍客里接入和使用Fair后,对Fair有3个比较大的感受:第一个感受是:保留Flutter原生开发习惯使用Fair不需要学习新的技术栈,也不用适应新的语法习惯,只需要按照Flutter原生的写法开发即可。第二个感受是:改造简单将Widget改造为动态页面,只需要加上几个注解即可,方便、实用。参考数据:58拍客接入Fair+3个页面改造排期:2天第三个感受是:bundle资源大小控制合理58拍客改造了3个页面,这3个页面总的bundle资源大小才8KB。最后,欢迎大家使用Fair,也欢迎大家为我们点亮Stargitclonehttps://github.com/wuba/fair.git如果想要加入Fair的交流群,可以先添加小秘书微信作者简介:陈有余:58同城,Android高级开发工程师
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 12:42 , Processed in 2.265519 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表