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 ChannelsFlutter通过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
参考资料
Flutter中文网:https://Flutterchina.club/
Dart论坛:http://www.cndartlang.com/
Flutter论坛:http://Flutter-dev.cn/
网友评论