Flutter原理与实践

Flutter的开源项目:https://www.jianshu.com/p/7b0642a27eb0

Flutter混合编程项目:https://www.jianshu.com/p/07131836ee13

一、初识Flutter

Flutter是移动跨平台开发UI框架,旨在帮助开发者使用一套代码同时开发自然流畅的Android和iOS应用。使用Flutter开发出来的应用符合不同平台的原生体验,让用户感觉就像在操作原生应用一样。

1、原生开发、RN开发、Flutter开发的架构图

图1 原生开发

传统的原生开发使用Native语言和Platform进行交互,通过调用平台API来实现App的功能。

图2 RN开发

RN通过JS访问平台UI组件,所以需要通过Bridge桥接器将JS转换到原生,在UI被频繁操作时可能导致性能问题。

图3 Flutter开发

为避免JS桥接器的性能问题,Flutter采用Dart语言,Dart使用预编译的方式编译多个平台的原生代码,这允许Flutter直接与平台通信,而不需要通过执行上下文切换的JS桥接器。

Flutter的UI组件和渲染器都从平台中移到了到用户的应用程序,所以虚拟机中的控件树是真实的控件树,渲染速度快。

Dart程序和执行数据编解码的平台之间仍然有个接口,但这个接口的速度比JSBridge高出几个数量级。

2、Flutter的架构

图4 Flutter架构

Flutter架构包括Framework和Engine两部分,Framework部分采用Dart语言编写,包括组件、渲染器等;Engine部分由C++实现,完成了平台无关性的操作。

二、Flutter提供了什么

1、不同平台的原生体验

图5 不同平台的原生体验

使用Flutter开发出来的应用符合不同平台的原生体验,让应用看起来跟系统更加协调,在不同平台的滚动操作、字体、图标应该和该平台上的其他应用保持一致,让用户感觉就像操作原生应用一样。比如,Android 和 iOS 的返回图标是不一样的。

2、丰富的UI组件

图6 丰富的UI组件

Flutter提供了丰富的可自定义的UI组件(Material Design和Cupertino(iOS-flavor)),没有使用原生组件进行渲染。

3、简化的布局

图7 简化的布局

Flutter最大的改进之一就是布局,布局都由Widget组成,Widget是Flutter应用程序的基本构建块,Flutter具有一致的对象模型: Widget。通过组合不同的Widget形成一个新的布局。

4、besides

除此之外,Flutter还有如下特性:

同一份代码开发iOS和Android。

响应式视图(无需虚拟DOM,直接在真实DOM更新) ,不需要JS桥接。

将AOT编译成本地代码(ARM)。

配备有丰富美观的可定制UI组件。

强大的开发工具,热重载。

三、Flutter开发

现阶段Flutter的开发有如下两种方式:开启一个全新的Flutter工程、在现有的工程中引入Flutter进行混合开发。可以参照如下步骤搭建环境:

1、安装Flutter

https://github.com/Flutter/Flutter/wiki/Using-Flutter-in-China

2、配置androidstudio

https://Flutterchina.club/get-started/editor/#androidsstudio

3、配置VSCode

https://Flutterchina.club/get-started/editor/#vscode

3.1全新的Flutter工程开发

图8 工程目录

Flutter的工程目录如上所示,Android和iOS目录分别存放了原生代码,已Android为例,仅需要一个MainActivity作为主界面入口;lib目录存放了Flutter的源码;main.dart是整个应用的入口;pubspec.yaml存放了配置信息。

图9 应用入口函数

main.dart是整个应用的入口,这里通过runApp来创建一个MaterialApp,主界面由HomePage实现。

3.1.1 UI组件

Flutter APP的所有界面都是由Widget组成的,StatefulWidget和StatelessWidget是Flutter提供的用于自定义控件的抽象类。

StatelesssWidget是无状态的,也就是不可变的。

StatefulWidget是有状态的,可以通过setState动态改变Widget的状态。

如果自定义的控件可以与用户进行交互,比如通过键盘输入内容、通过滑动屏幕移动滑块、点击时改变状态,又或者是随着时间的推移而变化,比如数据Feed会更新状态。这时应该选择使用StatefulWidget创建一个有状态控件。

如果自定义的控件仅依赖于对象本身的配置信息,仅仅是用于展示给定的信息,那我们应该选择使用StatelessWidget创建一个无状态控件。

3.1.2、主界面HomePage.dart

主界面是Material Design结构,包括了AppBar、侧滑Drawer菜单、和主体部分。

通过Navigator可以实现界面切换,主体部分由TabBarView组成。

3.1.3、网络请求

Flutter提供了标准的网络请求了JSON解析库。

图11 Flutter网络请求

3.1.4、FlutterMehodChannel

Flutter通过FlutterMehodChannel可以和原生进行交互。

图12 Flutter Channels      

Flutter通过MethodChannel和原生进行交换,这样在Dart中就可以调用到原生的API。

原生API接受Dart的调用:

图13 原生等待Flutter调用    

Dart通过MethodChannel调用原生API

图14 Flutter调用原生

3.2、Native Flutter混合编程

尽管Flutter技术很先进,但现阶段还有许多问题:

适配问题:虽说Flutter实现了跨平台,但还没能解决各个屏幕适配带来的问题。

性能问题:一些Android机器有性能和体验问题。

硬件问题:由于机器碎片化,官方的硬件组件也会crash。

生命周期问题:插件层对生命周期的监控,是App级别的,无法针对某一个页面。Flutter中控件也没有很明确的生命周期这一概念,就是两三种状态的切换,没有像React中的生命周期,更不用说像Native中的那样。

由于有这些个缺点,所以很多应用选择在现有的工程中引入少量的Flutter技术,这就需要混合编程。混合编程可以有如下两种形式:

3.2.1、FlutterActivity方案

图15 FlutterActivity方案       

Native界面在用户触发某个操作时进入Flutter主界面,并展示Dart编写的Widget。Dart Widget通过MethodChannel和FlutterActivity通信,然后再由FlutterActivity启动Native界面。这样就完成了Native和Flutter的混合编程。

3.2.2、FlutterModule方案

图16 FlutterModule方案      

Native通过FlutterModule创建FlutterView,FlutterView就是一个普通的View,可以进行View的操作。

    flutter channelmaster  切换分支

    flutter upgrade 更新Flutter

    flutter create -t

    module flutter_module创建模板

    根目录的setting.gradle修改上图配置

    应用的build.gradle添加  implementationproject(‘:flutter’)依赖

图17 FlutterView创建      

通过Flutter.createView创建View,然后给FlutterView设置MethodChannel进行通信,最后将Flutter加入到原生界面。

图18 FlutterView对应的界面

FlutterModule的main.dart根据对应的参数来调用Dart创建界面。由于FlutterModule在master分支,还没beta,存在黑屏问题,可以通过如下方式处理,在加载界面是显示一个ProgressBar,在FlutterView第一帧出来时再隐藏ProgresBar。

图19 优化黑屏

四、Flutter与原生开发的APP的区别

使用Flutter开发的APP和原生APP有如下区别:

安装包大小:

由于Flutter将渲染逻辑集成到APP内部,使得Flutter应用安装包比原生的应用包大。使用Flutter会给Android安装包增加8m左右的大小,iOS安装包增加16m左右。

动态化:

Flutter目前暂不支持动态化,Android通过更新Flutter的产物可以实现动态化,但iOS由于审核原因,实现成本较高。

启动速度:

图20 Flutter App启动速度      
图21 原生Appp启动速度      

五、实践的源码和参考资料

Flutter实现的GankIo

https://github.com/JasmineBen/FlutterGank

Android原生实现的GankIO

https://github.com/JasmineBen/GankImitation_MVP

参考资料

官网:https://Flutter.io/

Flutter中文网:https://Flutterchina.club/

Dart论坛:http://www.cndartlang.com/

Flutter论坛:http://Flutter-dev.cn/

各种资源:https://github.com/Solido/awesome-Flutter

官方插件:https://github.com/Flutter/plugins

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容