转载:http://dy.163.com/v2/article/detail/EA0O4PQ705376OPS.html

  Flutter简单介绍

  Flutter是Google打造的UI工具包,帮助开发者通过一套代码同时在iOS和Android上构建媲美原生体验的精美应用。

  开发者可以使用Flutter开始一个全新的应用,也可以把Flutter理解为应用内置的一个引擎,把这个引擎引入到现有的工程中。

  Flutter框架图如下:

  如上图所示,Flutter 框架被组织为多层结构,每个层都建立在前一层之上。上面统称 Framework,下面的一切都叫做 Engine。Framework完全使用 Dart 编程语言编写。Engine的绝大部分使用 C++ 编写,专属 Android 的部分用 Java 编写,专属 iOS 的部分则用 Objective-C 编写。Flutter的平台相关层很低,平台只是提供一个画布,剩余的所有渲染相关的逻辑都在Flutter内部,这就使得它具有了很好的跨端一致性。

  Dart主要由Google负责开发和维护的一种强类型、跨平台的开发语言。具有高生产力、快速高效、可移植、易学的OO编程风格和原生支持响应式编程等优秀特性。

  引言

  网易新闻项目本身很庞大,业务繁多,全部改为Flutter实现肯定是不现实的,在使用Flutter的前期阶段,我们挑选了相对独立的几个模块,在现有工程的基础上对其进行Flutter改造,以循序渐进的改造方式保证项目稳健,下面以Android为例,从以下几个方面介绍下此混合开发实践过程:

  集成方式

  开发模式

  工程管理

  原生端与Dart端通信

  混合栈及路由

  调试

  遇到的问题及解决方案

  稳定性保证

  Flutter集成方式

  如上介绍说明,开发者可以使用Flutter开始一个全新的应用,也可以把Flutter作为应用的一个module,把这个module引入到现有的工程中,因此有如下图的两种接入方式:

  

  网易新闻采用上图右所示的方式,以现有工程为主端的Flutter Module的方式集成到现有工程中去,具体集成方法可参考https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps,开发者在lib文件下使用Dart语言编写相应的业务代码。

  开发模式

  在网易新闻开发中的debug和release两种模式下,Flutter的构建和编译模式如下:

  

  debug模式下:Flutter编译是支持JIT的, 对于Dart开发者在主工程的build.gradle中以Compileproject方式接入Flutter工程,方便开发和调试;

  release模式下:Flutter的编译模式为AOT,业务Dart代码直接生成二进制指令文件,如下图所示,其中编写的Dart代码通过gen_snapshot编译器生成 vm/isolate_snapshot_data/instr,engine 通过Ninja 构建系统来生成flutter.jar,包括了engine c++部分的代码(flutter.jar中的libflutter.so),以及一套将Flutter嵌入Android的java类和接口(FlutterMain,FlutterView,FlutterNativeView等),最后通过gradle将这些Flutter相关代码编译和嵌入到原生App中。

  

  通过了解Flutter的构建和编译模式,可知Flutter module的接入最终的产物完全就是一个.aar包, 因此最终我们整个工程的release包futter是以.aar形式直接集成到现有工程中打包的,这样对于目前现有的工程的整个生产流程侵入干扰性达到最小。

  另外需要注意以下两点:

  minSdkVersion 需要至少为16

  主工程的build gradle插件版本要升级至3.x

  工程管理

  上面提到的Flutter module,以git submodule的方式分别引入到Android和iOS两端的主工程中

  

  这样对于Flutter Dart端开发者,在本地工程目录中保留.gitmodule文件,通过git module维护flutter 代码,达到dart开发者协同开发&调试;

  而Android和iOS两端native开发人员来说,Flutter module可以完全透明, 在运行时Flutter module会以.aar的方式compile到主工程,这样对原生开发者来说Flutter的接入是无感知的。

  原生端与Dart端通信

  Flutter虽然是个跨平台方案,在UI,手势触控,动画及基本的网络请求等上已经基本做到平台无关,但是在某些平台特性的功能上,还是必须要根据不同的平台做处理,且在前期过渡改造阶段,有些业务逻辑仍然需要原生端的支持,这就设计到与native的通信。

  

  从上图可以看出,dart端与原生端的通信是通过Flutter提供的channel机制达到双向通信,具体有三种channel:

  BasicMessageChannel: 主要是传递字符串和一些半结构体的数据

  MethodChannel: 传递方法调用

  EventChannel:数据流的通信

  其实通过源码可以看出,无论哪种传递,本质上都是数据的传递,通信都是通过BinaryMessage, 具体实现类是FlutterNativeView,使用的消息格式为二进制格式数据,三种channel只不过是上层包装的逻辑不同而已,具体使用哪个通信,根据具体业务实现来定。

  在网易新闻项目中,对于消息传递,制定了一套统一的消息协议规范,方便Android,iOS原生端和Dart端的通信。

  另外官网上提供的Plugin,基本上都是通过channel来调用原生能力,开发者可根据需要直接在pubspec.yaml中引入使用,另外在pub库中也有越来越多的plugin, 大家也可以自行开发通用的plugin使用。

  混合栈及路由

  以module的方式接入Flutter, 对于要改造的模块或者页面,在Activity或Fragment的onCreateView中创建FlutterView,Activity或者Fragment为FlutterView的一个容器;另Flutter的framework层提供的navigator管理控制Flutter内部的页面, 如下图中pageWidgetC1,C2,C3的都为Dart实现的flutter页面,而它们是处在同一个Activity中的,因此就有了混合栈的问题(原生栈和Flutter内部栈同时存在)。

  

  对于混合栈路由的处理,如下图左所示,一个Activity里有多个Flutter页面,Flutter之间的跳转切换由Flutter内部栈管理,不过相应的对于页面跳转动画,手势右滑跟随退出等效果也要同原生端效果再实现一套,且需要同Android,iOS原生端现有的保持一致性,但Android,iOS两端现有的本来就是不一致的,因此就有了如下右图所示的第二个方案,一个Activitiy对应一个Flutter页面,路由由原生维护一套,Flutter页面之间的跳转其实是Native的跳转,比如Flutter page1跳转Flutter Page2,需要page1通过约定的消息协议通知到Native,Native收到跳转Flutter页面的协议后会再开启一个承载FlutterView的Activity来绘制Flutter page2页面,但该方案对于跳转层级比较深的页面,多个FlutterView实例对于性能有一定的损耗,因为每个flutterView的底层对应一个engine, 且页面比较隔离,对于数据同步问题要通过native获取,当然对于第一个方案混合路由来说,在原生页面和Flutter页面交替出现的场景下,也同样会存在这些问题。

  

  这两种方案都是可选的,但都不是最优方案,Flutter设计的初衷应该是多以新的纯的Flutter工程为出发点来支持跨平台开发的,对于在现有工程改造的混合开发没有很好的支持,具体采用哪种方案,根据自己项目情况来定,或者更改Flutter的engine来优化内存和数据同步等问题。

  网易新闻因为前期选取的改造模块比较独立,一个模块对应一个Activtiy, 该Activtiy里有多个Flutter页面,对于跳转动画,手势右滑跟随退出等效果同Android原生端效果一致,且在统一路由跳转处增加配置项,可切换一对一方案,这样可以保证iOS的接入与原生的交互体验一致性,后续随着越来越多的业务模块改造,对于现有设计方案,我们会不断更新调整优化。

  调试

  Flutter hot reload是Flutter的一大亮点,可称之为神器,开发者有任何修改,都不需要重新启动应用,即可看到改动效果。进入Flutter module, 输入命令flutter attach。

  

  如上就说明连接成功,只要有改动,键盘敲击R或者r 即可看到更改。

  如果你运行命令后一直在waiting,可尝试杀死该应用进程后再重新进入相关Flutter页面就可连接上了

  遇到的问题及解决方案 SO库兼容性问题

  在Flutter官方只提供了4中CPU架构的so库,armeabi-v7a、arm64-v8a、x86和x86-64,其中x86系列只支持Debug模式,没有提供armeabi架构的库,而网易新闻上只保留armeabi的so文件。虽然我们可以通过修改engine等配置文件来编译出armeabi架构的so, 但是实际上现在市面上绝大部分手机设备都已经支持armeabi-v7a,其提供的硬件加速浮点运算指令可以大大提高Flutter的运行速度,且修改engine需要额外的版本维护,所以我们前期灰度期间在Flutter分支上直接屏蔽掉不支持armeabi-v7a的设备,直接使用armeabi-v7a的so文件。在编译阶段通过gradle构建将armeabi-v7a下的libflutter.so拷贝到armeabi目录下。

  包体大小问题

  引入Flutter后,通过上述flutter构建的图可以看出,最终产物so,icu, vm/isolate_snapshot_data/instr大小都是很可观的,对于Android来说,包体增大6M左右,随着业务代码的增多,包体将会更大,起初,我们采用动态下发这些文件以解决包体大小的问题,并验证了其可行性,但是这样处理有个问题,就是如果这些文件下载失败,该如何处理?此外官方团队也在重点优化包体大小,因此暂时放弃动态下发这一方案。

  资源共享问题

  在flutter中引入图片资源,需要在lib下建立image包,并需要在pubspec.yaml文件下的assets下声明; 对于混合开发来说,如果两端都需要的图片资源,就要存在两套,这样一来增加了包体大小,并且需要维护两套资源,最初为了实现两端共享本地资源的问题,解决方案是在dart端通过BasicMessageChannel根据图片名称获取native端存在的图片资源,但与此同时产生的另外一个问题就是同一份资源在Android和iOS原生端的资源命名不一致,为此开发成本较大,带来收益较小,暂放弃本地资源共享这一方案。

  稳定性保证

  对于稳定性保证采用如下方案:

  选取个别渠道上进行灰度测试;

  动态接口开关控制用户逐渐放量测试;

  通过FlutterError.onError和runZoned捕获异常,异常错误信息用channel机制通过native上报到崩溃收集系统(fabric-Crashlytics)。

  上线情况:网易新闻Flutter用户量由4%逐渐放量到目前10%, 在几个版本的迭代过程中,异常收集达到万分之一,已达到生产标准。

  当然我们还在继续,我们iOS也相继接入,实现方案也在不断调整和优化,官方的Flutter团队也在努力不断优化和完善,希望整个Flutter生态越来越好,由于个人水平有限,有不对之处望指正,最后,欢迎加入和关注我们

网易新闻客户端Flutter混合开发实践相关推荐

  1. Flutter开发之《网易新闻客户端Flutter混合开发实践》笔记(52)

    摘自:网易新闻客户端Flutter混合开发实践 引言 网易新闻项目本身很庞大,业务繁多,全部改为Flutter实现肯定是不现实的,在使用Flutter的前期阶段,我们挑选了相对独立的几个模块,在现有工 ...

  2. 视频教程-Flutter布局实战网易新闻客户端-flutter

    Flutter布局实战网易新闻客户端 Flutter书籍作者.曾任职于多家互联网大型企业,担任移动端项目技术负责人,主导研发和攻关技术难题,项目涉及教育.金融.医疗.交通.车载设备.智能家居等众多领域 ...

  3. 58同城 Flutter 混合开发探索与实践

    点击"开发者技术前线",选择"星标????" 在看|星标|留言,  真爱 导语 本文主要介绍将Flutter应用到已有Native项目中混合开发遇到的问题及解决 ...

  4. IOS开发——仿网易新闻客户端

    IOS开发--仿网易新闻客户端 本文没有内容,传个资源 衔接地址:http://download.csdn.net/detail/u012881779/7152281 左侧导航部分: 新闻版块 订阅版 ...

  5. 技术干货 | Flutter 混合开发基础

    导读:Flutter 支持以独立页面.甚至是 UI 片段的方式,集成到现有的应用中,即所谓的混合开发模式.本文主要谈谈 Android 平台下, Flutter 的混合开发与构建. 文|李成达 网易云 ...

  6. 模仿网易新闻客户端(RSS版)(一)

    一.摘要 这几天找工作闲来没事,偶然在一个论坛上面看到有人模拟网易新闻客户端首页顶部那个组件效果,一时兴起,也来自己动手完整地模拟一个,包括顶部的特效组件和底部的类似于TabHost的组件.下面就动手 ...

  7. 新闻资讯小程序开发实践

    新闻资讯小程序开发实践 在腾讯小程序上线一周年之际,公司又决定把App产品部分内容在小程序上实现.就在小程序刚上线的时候,公司也有一款产品进行了小程序的研发,但后续没有持续的维护.这过了一年的时间,微 ...

  8. android 网易新闻 详情页面实现,Android实现网易新闻客户端首页效果

    关于实现网易新闻客户端的界面,以前写过很多博客,请参考: 今天用ViewPager + FragmentAdapter + ViewPagerIndicator来实现. ViewPagerIndica ...

  9. 模仿网易新闻客户端(RSS版)(二)

    一.摘要 继上一篇博客<模仿网易新闻客户端(一)>之后,笔者继续开发我们自己的"网易新闻客户端",由于找不到现成的url新闻链接地址,所以这里就用RSS订阅所提供的ur ...

最新文章

  1. 6、WHERE:条件查询数据
  2. oracle ebs form视频,ORACLE EBS FORM利用模板开发步骤
  3. IDEA手动添加jar包
  4. 使用互斥体使程序只运行一个
  5. python3安装mysqlclient_Python3 安装mysqlclient错误处理(MAC版)
  6. 运行第一个 docker image 并在浏览器中查看
  7. python怎么另起一行阅读答案_一行代码将Pandas加速4倍
  8. 面试官:请讲一下Redis主从复制的功能及实现原理
  9. ASP.NET中的回调技术(CallBack)
  10. DropDownList下拉框多选
  11. 主板h110能装linux吗_华硕H110T +i3 8100T 组装黑苹果Mac mini安装教程
  12. c语言笔试题7(25),嵌入式软件工程师C语言笔试题(7页)-原创力文档
  13. CS224N 笔记一
  14. EKF扩展卡尔曼滤波估算SOC/锂电池SOC估算估计/EKF估算SOC 基于二阶RC模型搭建
  15. 深入理解Android之Xposed详解
  16. 如何删除电脑上一些恶意安装软件?
  17. opencv训练自己的模型,实现特定物体的识别
  18. 如何在Microsoft Word中转录音频
  19. 线性表中的尾插法双链表的学习
  20. Docker11_2:Docker腾讯云仓库

热门文章

  1. js(javascript)数组去重
  2. Windows这些自带应用一定不要删,否则会直接影响到电脑使用
  3. 从plugin路径中读取依赖并构造对象——Azkaban源码解读之Alert plugin实现(一)
  4. 基于tableau进行APP高频访问场景数据分析
  5. 查看suse linux版本
  6. unity spine 进阶使用
  7. 【详解】NLP之常用数据集详解
  8. 《音视频开发进阶指南:基于Android与iOS平台的实践》源码下载地址
  9. 简易的自动抢购脚本,适用于各种限购产品,你懂得!
  10. vue中background-image图片路径问题