Android开发Android开发经验谈Android技术知识

Flutter原理与实践

2018-09-29  本文已影响77人  JasmineBen

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

上一篇下一篇

猜你喜欢

热点阅读