首发 | 闲鱼公开多年 Flutter 实践经验

1894次阅读  |  发布于4年以前

阿里妹导读:Flutter从诞生到现在,已经成为了跨端开发的领跑者。闲鱼应用在flutter能够以模块形式存在前,进行了很长时间的混合app架构的探索,对原生工程进行较多改动,在官方推出flutter模块模式后,我们进行了大量调研,最终推出了一套开箱即用的混合工程脚手架flutter-boot,帮助大家快速搭建混合工程。

Google Flutter 产品经理推荐,精解Flutter企业级实践,揭秘亿级流量背后的技术秘籍,工程师不容错过的学习宝典的《Flutter in action》,今天正式发布,文末下载。

作者 | 兴往、向志明、马引

背景

国内外越来越多的公司走上了flutter探索之路。Flutter的主要开发模式分成两种,一种是独立app的模式,以flutter为主,原生工程会被包含在flutter工程下;另一种是让flutter以模块(flutter module)的形式存在,分别集成在已有的iOS和android原生应用下,此时原生工程可以在任何的目录结构下,和flutter工程地址不产生关联,但需要在原生工程结构中声明flutter工程的本地地址。

简介

flutter-boot核心解决了混合开发模式下的两个问题:flutter混合开发的工程化设计和混合栈。那flutter-boot是如何解决的呢?

首先在工程化设计的问题上,flutter-boot建立了一套标准的工程创建流程和友好的交互命令,当流程执行完成后,即拥有了混合开发的标准工程结构,这一套工程结构能够帮助我们同时拥有flutter和native(原生)两种开发视角,本地flutter开发和云端flutter构建两种flutter集成模式,其效果如图:

另外在混合栈的问题上,flutter-boot能自动注入混合栈依赖,同时将核心的混合栈接入代码封装后注入到原生工程内,在用户按提示插入简单几行模版代码后,即可看到混合栈的效果。 使用flutter-boot搭建的混合工程,开箱即可使用,接下来让我们了解下flutter-boot解决这些问题的详细过程。

开源地址

https://github.com/alibaba-flutter/flutter-boot

工程化设计

了解官方的Add Flutter to existing apps项目

在了解flutter-boot的工程化设计细节前,我们需要对Google官方提供的Add Flutter to existing apps方案有一个初步的了解。Add Flutter to existing apps项目会引导我们以module的形式创建flutter,module形态的flutter的工程结构如下:

some/path/
  my_flutter/
    lib/main.dart
    .ios/
    .android/

在官方的工程结构下,.ios和.android是运行flutter时的模版工程,在flutter工程目录下运行时即通过这两个工程来启动应用。那我们如何让原生工程和产生关联呢?这里的关联会分成三个部分,分别是flutter的framework,flutter的业务代码,和flutter的插件库。其中flutter插件库分成 flutter plugin native(即插件原生代码)和flutter plugin dart(即插件的dart代码)两个部分。这四部分的差异在于:

因此flutter framework只需要在依赖管理中声明即可,flutter plugin native可以直接以源码的方式集成,flutter plugin dart只有在被业务代码引用时才有效,因此和业务代码一样,需要支持dart代码的调试模式和发布模式,因此dart代码的关联会侵入到app的构建环节,根据app构建的模式来决定dart代码的构建模式。

具体的实现,拿iOS来举例,我们会在podfile文件中增加一个自定义的ruby脚本podfilehelper的调用,podfilehelper会声明flutter framework的依赖,声明flutter plugin native的源码引用,同时声明业务代码的路径。接下来会介入构建流程,在xcode的build phase内加入shell脚本xcode_backend的调用,xcode_backend会根据当前构建模式,来产出dart构建产物。

flutter-boot的补充

对于官方的混合工程项目,我们在体验后发现有如下的问题:

1. 文件或配置的添加为手动添加,流程较长。

2. 不支持在flutter仓库下运行原生工程。

3. 不支持flutter以独立代码仓库部署时的远端机器构建。

因此在flutter-boot脚手架中,为了解决这些问题,我们把混合工程的部署分为create,link,remotelink,update四个过程。

★ create

create过程目的在于帮助我们搭建一个flutter module,包括flutter module的创建和git仓库的部署,flutter module创建命令调用前,我们会做基础的检查来让工程位置和命名的规范满足官方的条件。在git仓库部署时,我们会在gitignore中忽略部分文件,同时我们会对仓库的状态进行检查,在仓库为空时,直接添加文件,在仓库非空时,会优先清理仓库。

★ link

link过程目的在于关联本地的原生工程和flutter工程。关联的过程中,我们会先请求获取flutter工程的地址和原生工程的地址,然后我们将上面提到的需要手动集成的部分通过脚本的方式自动集成;为了获得flutter开发视角(即flutter工程下运行原生工程),我们将原生工程进行了软链接,链接到flutter工程的ios目录和android目录,flutter在运行前会找到工程下的ios或android目录然后运行,在flutter工程下运行iOS工程会存在一个限制,即iOS工程的target需要指定为runner,为了解决这个问题,我们将原生工程的主target进行了复制,复制了一份名为runner的target。

同时,为了支持远程构建的模式,我们flutter仓库本地路径的声明根据构建模式进行了区分,封装在自定义的依赖脚本中,例如在iOS工程内,我们会添加fbpodhelper.rb脚本文件。然后将flutter仓库本地路径添加到了配置文件fbConfig.local.json中。

★ remotelink

update remotelink过程目的在于远端构建模式下,能够获取flutter仓库的代码,并在远端机器上进行构建。在远端构建模式下,我们会侵入依赖管理的过程,在依赖获取时,拉取flutter仓库的代码,将代码放置在原生工程的.fbflutter目录下,并将该目录声明为flutter仓库本地路径,拉取flutter代码并进行本地部署的过程,我们称之为update过程。

这样在远端构建时就能和本地构建如出一辙。 那远端模式和本地模式如何区分呢?为了区分远端模式与本地模式,我们将远端的flutter仓库信息记录在fbConfig.json,同时在gitignore中忽略fbConfig.local.json文件,这样只需要初始化混合工程的工程师运行一次remotelink,其他的开发协同者将不用关注远端构建的配置流程。

★ init

为了方便快速搭建,我们提供了一个命令集合,命名为init,我们将必备的环节以命令行交互的模式集成在了init命令中。

混合栈

混合栈是闲鱼开源的一套用于flutter混合工程下协调原生页面与flutter页面交互的框架,目前是混合开发模式下的主流框架。在混合栈开源后,我们关注到大量开发者在集成混合栈时会产生各种环境配置或代码添加导致的集成问题。因此我们决定提供一套快速集成的方案。要做到快速集成我们面临两个问题:

1. flutter和混合栈的版本兼容;

2. 混合栈demo代码封装及插入。

版本兼容问题

目前混合栈发布版本为0.1.52,支持flutter 1.5.4。当flutter升级时混合栈势必要进行适配,即我们集成的混合栈版本也需要变更。因此我们将混合栈的版本配置通过文件进行维护,记录当前flutter所需要的混合栈版本。在初版的flutter-boot中,我们限定了混合栈的版本号,在新版本混合栈发布时,我们将开放版本选择的功能。

代码封装及插入问题

在调研了混合栈的使用过程后,我们将混合栈需要的demo代码分成了四个部分:

1. flutter引擎的托管;

2. 页面路由的配置 ;

3. demo形式的dart页面 ;

4. 原生的测试跳转入口。

★ flutter引擎的托管

引擎的托管我们依赖于应用的初始化,由于初始化过程随着应用的复杂程度提升而提升,因此目前我们提供了一行代码作为接口,使用者在应用初始化时加入这一行代码即可完成托管。

★ 页面路由的配置

demo形式的dart页面,路由配置即路由到某个标识符时,flutter或原生页面需要识别并跳转相应页面。路由的配置需要在原生和flutter两侧进行部署。在原生侧,我们将混合栈的demo路由代码进行了精简,然后添加在了原生工程的固定目录下。由于iOS仅添加代码文件是不会被纳入构建范围的,因此我们封装了一套iOS侧的代码添加工具来实现文件的插入。在flutter侧我们对main.dart文件进行了覆盖,将带有路由逻辑的main.dart集成进来,同时提供了demo dart页面的创建逻辑。

★ 原生的测试跳转入口

为了方便使用者快速看到混合工程的跳转模式,我们在iOS和android双端封装了一个入口按钮和按钮的添加过程,使用者在测试的页面手动加入一行代码,即可看到跳转flutter的入口。

效果

在使用flutter-boot前,开发者可能要花费数天来进行混合工程搭建,现在,使用者只需要调用一个命令,加入两行代码即可完成混合工程的搭建,大大降低了开发者的开发成本。但flutter-boot的使命还未达成,我们期望使用者能更加流畅的进行flutter开发,未来我们会优化多人协同的开发流程,完善持续集成环境的搭建,让使用者拥有更佳的开发体验。

Flutter开源工具大集合

闲鱼Flutter应用框架Fish Redux、开发利器AspectD、FlutterBoost等一众开发工具正式开源,现在《Flutter in action》一次帮你找全了。开源地址+技术解析,手把手教你Flutter应用框架和混合开发原理!

闲鱼Flutter企业级应用实践

随着无线,IoT的发展,5G的到来,移动研发越发向多端化发展。传统的基于Native+Web+服务端的开发方式,研发效率低下,显然已经无法适应发展需要。

而Flutter是Google开源的跨端便携UI工具包,除了具有非常优秀的跨端渲染一致性,还具备非常高效的研发体验,丰富的开箱即用的UI组件,以及跟Native媲美的性能体验。由于它的众多优势,也使得Flutter成为了近些年来热门的新技术。

在这本书中将详细讲解闲鱼Flutter&FaaS云端一体化架构,和闲鱼基于Flutter的架构演进与创新,学习一套全面的Flutter架构应用方案。

混合开发实践指南

你将在这里看到闲鱼技术团队利用Flutter技术改造和上线复杂业务的混合工程改造实践、抽取Flutter依赖到远程的实现细节、以及使用Plugin桥接获取设备信息、使用基础网络库等混合开发实践指南。

这些实践遍布闲鱼各大业务线和应用场景,为你使用Flutter打造自己的研发体系探索一条实践之路。

Flutter的深入进阶教程

在获得开源工具与开发实践指南后,你还将在本书中学到Flutter的更多应用场景。

它们包括了如何低成本实现Flutter富文本、设计一个高准确率的Flutter埋点框架、Flutter外接纹理、可定制化的Flutter相册组件等等深入进阶内容。

Copyright© 2013-2019

京ICP备2023019179号-2