作者|王敏君(华泰证券前端技术团队) 编辑|覃云 近年来,移动互联网迅猛发展,业务需求频繁更新,业务内容动态化需求急剧增加,纯原生开发已经无法满足业务快速增长的需求,因此诞生了多种跨平台开发框架,如 H5+ 原生开发、React Native 和 Weex ,但这两年最受开发者青睐的莫过于 Flutter。目前,很多应用都集成了 Flutter,我们团队也在涨乐财富通上实现了完整 Flutter 的集成过程,以下篇幅会具体介绍整个集成过程。 涨乐 Flutter 实践(以 iOS 为例)

此次实践主要是为了验证整个流程,为后续大规模应用 Flutter 做铺垫,因此我们选择了一个业务相对简单的“技术论市”页面进行改造,该页面之前是 H5 实现的列表页,点击栏目会跳转到另一个 H5 页面详情页。

改造之后,原生界面点击按钮会打开 Flutter 列表页,点击 Flutter 页面的栏目会跳转到 H5 页面,点击返回可依次返回到上一个界面。从图中可以看出,整个流程的使用体验非常流畅。

组件化集成

如何将 Flutter 代码集成进现有工程是我们遇到的第一个挑战。Flutter 官网 (https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps#ios) 提供了一种解决方案,但存在以下缺陷:

  1. 需要修改主工程的配置,入侵原有工程;

  2. 工程运行需要 Flutter 环境,而在实际开发中并不是所有的团队成员都会参与到 Flutter 的开发,安装 Flutter 环境对于那些不需要 Flutter 开发的成员来说显然不合理。

官网的方案行不同,我们必须另辟蹊径。研究 Flutter 的编译脚本xcode_backend.sh发现,只要将 Flutter 编译产物放入主工程就能运行 Flutter 模块。为了便于管理,涨乐财富通采用私有 pod 管理编译产物的方式来集成 Flutter。

Flutter 工程的编译产物包含三个部分,分别是:

1.App.framework:所有的 Dart 代码,包括业务代码和依赖的第三方 package 代码,在 Debug 模式下只是一个空壳,在 Release 模式下是所有代码生成的机器码。

2.Flutter.framework:Flutter 的 SDK。

3.flutter_assets:Flutter 资源文件,包括字体、图片等。

创建私有 pod 用来管理这些编译产物,podspec 的核心内容如下:

  s.source_files = 'htflutter_product_debug/Plugin/**/*'s.vendored_frameworks = 'Framework/*.framework', 'Framework/engine/*.framework's.resources = 'Framework/flutter_assets'

主工程需要集成 Flutter 模块时,只需要在 podfile 中依赖该私有 pod 即可。

混合栈管理

引入 Flutter 模块后,需要考虑的就是如何管理混合栈。在现有应用中,已经存在原生 + 网页的混合栈,如今引入了 Flutter 需要解决这三者如何嵌套。混合栈管理的方案必须具备以下特点:

  1. 原生、H5、Flutter 页面三者能相互调用,并且用户感觉不到差异;

  2. 尽量减少资源消耗;

  3. 每个页面的生命周期保持完整。

为此,我们借鉴了闲鱼团队开源的混合栈管理方案,并与我们现有的路由管理方案相结合,在涨乐上实现了混合栈管理,具体架构图如下:

  • 页面跳转使用统一的路由管理。

涨乐财富通使用路由管理器来统一管理页面。当需要打开一个 Flutter 页面时,只需要像原来一样,发送一个打开 Flutter 的路由,并携带参数用来标识具体的页面。路由管理器识别到是 Flutter 路由后会创建新的WrapFlutterViewController并压栈。WrapFlutterViewController会使用 FlutterViewController单例作为其子 VC,利用传递过来在参数在FlutterViewController内部打开具体的 Flutter 页面。

  • 所有的 Flutter 页面共用一个 Flutter 实例,iOS 使用 FlutterViewController,Android 使用 FlutterNativeView

共用一个 Flutter 实例,既可以使得 Flutter 页面之间实现数据通信和共享,也可以减少额外的资源消耗。因为每一个 Flutter 实例会启动三个线程,分别是 UI 线程、GPU 线程和 IO 线程,只创建一个 Flutter 实例减少了资源的使用。

  • 每一个 Flutter 页面对应一个原生页面。

每次 push/pop 一个 Flutter 页面,一方面会操作 Flutter 实例内部的导航栈,另一方面在外部会 push/pop 一个原生的页面,这样可以确保 Flutter 页面和原生页面的同步。

自动化

整个 Flutter 的开发过程分为以下两大步骤:

  1. 编写 dart 和 plugin 代码并生成 App.framework,Flutter_Asset 文件夹和 Flutter.framework;

  2. 将编译产物集成到 iOS 主工程;

自动化需要解决几个关键问题:

  1. 如何区分 debug 和 release 模式下的产物包

  2. 自动化的流程应该如何控制

针对第一个问题,我们的解决办法是创建两个 repo,htflutter_product_debughtflutter_product_release,开发使用 debug 产物,生产使用 release 产物。

第二个问题,我们参考的是 CocoaPods 的 pod 发布流程,将 Flutter 主工程作为一个私有 repo 来看待,通过 tag 触发脚本生成产物,再 push 到htflutter_product_debughtflutter_product_release。具体流程如下图:

  1. 首先htcftflutter是我们的 Flutter 主工程,包含所有的 Dart 源代码和 plugin 代码。

  2. 通过 tag 名触发脚本,编译出两种模式的产物,例如 tag:debug_1.0则编译出 debug prudoct。

  3. 将产物推送到远端产物 pod repo(这一步实际上类似 pod repo push)。这一步相对复杂一点,

首先需要 clone 远端的产物 pod 到当前的某个临时文件夹,然后将 Flutter 主工程中编译的产物拷贝到临时文件夹中,其中包含 App.framework,flutter_assets 文件夹以及 Flutter.framework,另外还有 plugin 相关文件。前面三个都好办,直接拷贝即可,plugin 比较麻烦,plugin 的代码通过 package 的形式引入到工程中,并不在 Flutter 主工程,需要从.flutter-plugins文件中读取到各个 plugin 到路径,然后到对应到路径进行拷贝。拷贝完成之后,再通过脚本完成git的相关操作即可,最后 push 完成,删除临时文件夹,这样htcftflutter不感知整个脚本执行过程。

4.iOS 主工程集成 Flutter 产物 pod,默认情况下podfile中依赖htflutter_product_debug, 主工程打 release tag 时,触发脚本将依赖修改成htflutter_product_release,并执行pod update。相关脚本如下:

 tool = HTTool.new(mode) //debug/releasetool.build_ios() # 编译产物tool.clone_flutter_product_repo() #clone product repotool.copy_products()   # 拷贝产物tool.copy_plugin_code() # 拷贝 plugin 原生代码tool.updateSpecVersion() # 更新版本tool.push_flutter_product_repo() #push to product repotool.remove_product_repo()#delete product repo after push

降级策略

Flutter 还处于快速迭代发展的阶段,正式上线可能存在不确定的风险,为此我们设计了具体的降级方案,应对 Flutter 发生异常的情况。

  1. 应用启动时,服务器会下发 Flutter 降级配置表,key 是需要降级的 Flutter 页面路径,value 是需要执行的降级路由操作;

  2. 路由管理器响应 Flutter 路由时,会首先判断需要打开的 Flutter 页面是否需要降级,若需要,则会执行配置表中的路由操作,降级到网页;反之则正常跳转到 Flutter 页面。

实践结果

1. 安装包大小

引入 Flutter 之前,涨乐财富通的安装包为 94MB,引入之后大小为 100MB,发现增大了 6MB,这其中主要是引入了 Flutter 的 SDK,增加的大小在可以接受的范围。

2.FPS 和 GPU

从上图可以看出,Flutter 的 FPS 接近 60,和原生效果基本一致,而 H5 的 FPS 在 50 左右,远不如 Flutter 优秀。两者的 GPU 使用率基本相同。

3. 内存

内存表现方面,H5 页面使用的内存要小于 Flutter。

4.CPU

从 CPU 的占用率来看,Flutter 占用的 CPU 要远远小于 H5 页面。

总 结

从我们的实践结果来看,Flutter 在性能方面拥有绝对优秀的体验,但 Flutter 的开发生态还不够成熟,完全取代原生开发实现跨平台为时尚早,但对于一些追求一致性、高性能的界面可以尝试采用 Flutter 实现。我们涨乐财富通开发团队也会持续跟进 Flutter 的发展,将 Flutter 推广应用到更多业务场景中。

flutter图片点击跳转_使用Flutter之后,我们的CPU占用率降了50%相关推荐

  1. 使用Flutter之后,我们的CPU占用率降了50%

    近年来,移动互联网迅猛发展,业务需求频繁更新,业务内容动态化需求急剧增加,纯原生开发已经无法满足业务快速增长的需求,因此诞生了多种跨平台开发框架,如 H5+ 原生开发.React Native 和 W ...

  2. 使用 Flutter 之后,CPU占用率降了 50%

    点击上方"开发者技术前线",选择"星标" 0:00在看 真爱 作者:王敏君(华泰证券前端技术团队) 来源:前端之巅 近年来,移动互联网迅猛发展,业务需求频繁更新 ...

  3. flutter图片点击跳转_Flutter系列之Platform Channel使用详解

    PS:逐渐体会到关键少数原则的重要性,接下来就是付诸实践了,另外科创50ETF明天开始限额销售,可以适当关注或入手一点. 前面几篇文章介绍了 Navigator 组件.Flex 布局.图片加载.Wid ...

  4. java线程 cpu占用率_多线程程序 怎样查看每个线程的cpu占用

    可以用下面的命令将 cpu 占用率高的线程找出来: ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu 这个命令首先指定参数'H',显示线程相关的 ...

  5. flutter 图片转base64_京东技术中台的Flutter实践之路

    作者 | 京东 ARES 跨端团队 编辑 | Yonie 在 2019 年,Flutter 推出了多个正式版本,支持的终端越来越多,使用的项目也越来越多.Flutter 正在经历从小范围尝鲜到大面积应 ...

  6. flutter图片聊天泡泡_flutter/dart聊天实例|flutter仿微信

    > Flutter 是 Google 开源的 UI 框架,能高效构建多平台精美应用. > [FlutterChat聊天室项目](https://juejin.im/post/5ebb5c4 ...

  7. 微信小程序02-轮播图实现与图片点击跳转

    实现效果: 前言 在小程序01中,已经学习了如何制作底部导航栏,本节让我们一起学习如何制作轮播图,以及点击轮播图完成页面跳转. 实现过程 注:(1)前期学习,我这里用的本地的图片,后期的话,会对接后端 ...

  8. html 图片点击查看大图_【神游千年,大美敦煌】北魏-260窟【高清大图】

    [神游千年,大美敦煌]北魏-260窟[高清大图] --------------------------------------------------------------------------- ...

  9. flutter怎么添加ios网络权限_使用Flutter控制蓝牙通讯

    背景知识视频教程 Dart和Flutter:完整的开发人员指南 - 国外课栈​viadean.com Flutter使用Firestore构建复杂的Android和ios应用 - 国外课栈​viade ...

最新文章

  1. Hinton 发表新作探索流体胶囊网络 | AI日报
  2. Oracle 同义词的创建及其作用
  3. http keep-alive
  4. 图像处理(十三)保刚性图像变形算法-Siggraph 2004
  5. Win8 Metro(C#)数字图像处理--2.35图像肤色检测算法
  6. c ++产生不同的随机数_C ++程序生成随机密码
  7. c++ winpcap开发(1)
  8. 管天管地管空气!谷歌探索用CV估算空气质量
  9. python中的多线程求值串行和并行_python多线程和多进程——python并行编程实验
  10. 争取来的酷狗前端面试 共勉之
  11. [给创业公司的原生云] ②Spine L1
  12. API 接口加密及请求参数加密
  13. leetcode刷的一些杂题
  14. 输入偏置电流时钟馈通
  15. 怎么检测计算机硬件好坏,鲁大师如何检测硬件好坏?硬件好坏检测方法介绍
  16. 基于Ernie-3.0 CAIL2019法研杯要素识别多标签分类任务
  17. 大数据培训ClickHouse表引擎
  18. APS应用案例|纽威阀门实现高效排产
  19. autorun.inf文件
  20. 动态二进制插桩原理与实战

热门文章

  1. SAP Spartacus storefront.component.html 怎么关联到其他的页面
  2. Angular NgModule 中的 declarations 和 exports定义
  3. 网友提问:关于CX_VSI_SYSTEM_ERROR异常,Fiori病毒扫描参数文件
  4. SAP Spartacus里的产品主数据显示的数据源
  5. Angular的property binding一个例子
  6. SAP CRM WebClient UI如何将后台存储的timestamp时间戳转换成本地时间
  7. 介绍一个前端页面开发必备神器,chrome扩展,设备模拟器
  8. jQuery.sap.declare(cus.crm.notes.ext.Component);
  9. SAP UI5 this.oModel.createBindingContext will trigger odata request
  10. Fiori应用里如何隐藏prospect字段