Flutter初探

flutter

文章内容是我在学习Flutter过程中对知识点的梳理和总结。如有不对的地方,欢迎指出。

2018年前 H5的性能瓶颈和RN的停更 导致业界对跨平台开发失去信心。直到2018年10月Google推出首个Flutter跨平台解决方案,打破整个移动开发的方向。

去年MWC大展上发布首个Beta版后,Flutter 1.0正式版于2018年12月召开的Flutter Live 2018上正式发布。今年2月27在巴塞罗那召开的MWC发布会上,Google正式发布了Flutter跨平台UI框架的1.2版本。新版本最大的改变就是引入了对Android App Bundles的支持,可有效打包Android APP并创建即时应用的最新技术。此外该框架还帮助开发者接受应用内支付奠定了基础,并添加了很多基于Web的工具。

Flutter 的发展速度远超我们的想象。作为Google的亲儿子,未来一定会大力发展Flutter的,所以现在学习Flutter是比较好的优势。再看一下招聘情况,以Boss直聘为例,目前已经陆陆续续有公司在招聘Flutter开发工程师了,并且公司相对比较高。


Boss直聘Flutter招聘

Flutter是什么?

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。

Flutter可以和现在的工程相结合,拥有比较好的开发体验,它有一个热重载(hot reload)技术,让我们改变UI之后,及时的看到UI效果,并且保证我们上一次测试的状态。

Flutter拥有很丰富的UI组件,如:material cupertino,可以构建一个灵活的且富有表现力的UI。我在工作过程中经常和设计师沟通,他们经常使用苹果的设计风格进行设计,这导致我们的产品基本全都使用IOS的设计风格,之前一直要自定义VIew去实现,十分复杂。现在我们有了Flutter,用Flutter内置的UI组件库,我们很容易的就可以做到这一点。

Flutter它还有比较好的性能,几乎可以和原生应用相媲美,甚至在Android低端机上比原生的表现还要优异。难道Flutter这么好的技术只能在移动平台上去使用吗?很显然Google的野心可不止如此,目前我已知的Flutter支持的平台已经有Android IOS Web Windows LinuxMac OS ,除此之外,Flutter还支持嵌入式。

这是三个平台的SDK,有兴趣的老铁可以先Star,后续慢慢做研究。

Flutter: https://github.com/flutter/flutter
Desktop: https://github.com/google/flutter-desktop-embedding
WebSite: https://github.com/flutter/website

目前的跨平台解决方案

  • Web/Hybrid

也被称为 Hybrid 技术,它基于 Web 相关技术来实现界面及功能(代表框架:phonegapcordova)。

  • JSCore

通过虚拟Dom树来构建UI,映射成原生UI组件,通过JSCore桥接调用原生服务(代表框架:ReactNativeWeex)。

  • Native

将某个语言编译为二进制文件,生成动态库或打包成 apk/ipa/xap 文件(代表框架:Flutter)。

为什么选择Flutter

网上有很多Flutter与其他跨平台解决方案的多维度对比的资料(建议了解一下RN与Flutter的对比),感兴趣的可以查阅一下,这里就不一一列举了。

个人的观点是:Flutter是一场革命!

  • 跨平台性

Flutter基于图像绘制引擎进行渲染,在不同平台下绘制效果是绝对一致的,能做到真正的跨平台,一处写处处运行。

  • 性能优异性

不同于H5通过DOM渲染 和RN映射组件,Flutter直接基于native进行绘制。性能上完全超过原生。

  • 热重载性

Android原生开发会遇到“编译-打包-安装“三部曲。开发效率迟迟得不到提升。热重载技术在Flutter内完美体现。

Flutter详情介绍

  • Dart语法编译

Dart 是一种弱类型、跨平台的客户端开发语言。具有专门为客户端优化、高生产力、快速高效、可移植易学的风格。Dart主要由Google负责开发和维护。

  • Flutter插件

Flutter使用的Dart语言无法直接调用Android系统提供的Java接口,这时就需要使用插件来实现中转。Flutter官方提供了丰富的原生接口封装。

Flutter系统架构

Flutter分为三大部分:

1.由Dart语言负责的Framwork层

2.Dart语法执行器

3.Skia图像处理引擎


Flutter系统架构

其实Flutter的核心是Skia,Dart更像是在外面包装了一层,然后去调用Skia的接口,最终都是被Skia去执行;Text是一些组件,只不过通过Dart去执行,但最终也是被Skia去执行,既然Skia这么重要,那我们简单了解一下吧!

Skia引擎详解

Skia
2005年Skia图像处理引擎成立,用来展示Chrome 火狐 和其他Google自家的产品使用。
2007年 第一个Android系统问世,于是Google开发者将Skia移植到Android平台。
Skia作为一个2D的图形系统,包括绘图,渲染,显示图片都是用Skia完成。

那Skia是如何渲染图片和控件的呢?

1.渲染图片

我们以BItmap为例:在加载一张图片的时候,我们可通过Bitmap去加载,一般两种方式,第一种通过Bitmap.createBitmap()方式创建,第二种是通过 BitmapFactory方式,但其实两种方式是一样的,第二种会调用第一种的代码,所以我们直接通过Bitmap.createBitmap()去看源码是如何实现的。
随便找一个BitMap.createBitmap()入口,进去会发现有很多createBitmap()方法重载,一路疯狂点击进入,最终我们找到一个不一样的方法nativeCreate(),如图:

Bitmap.createBitmap源码截图

好,胜利就在眼前,我们继续点进去。咦!我们惊奇的发现是竟然调用的是native方法。
通过native这个方法来看,我们的一张图片生成的内存放在哪个区域是不是就很明显了呢?既然是调用了native方法返回的Bitmap,那肯定就是native堆去开辟内存对不对。那我们的Bitmap.java算什么呢?它其实就相当于一个中介者,相当于一座桥,它连接着java层又连接着native层。
nativeCreate

这时候我们想点nativeCreate()去看如何实现的,但点不进去了,那我们还要不要继续往下找呢?
既然我们要看skia,那肯定是要的,怎么办呢,这时我们就要去看Android系统源码了。

Android系统源码下载
我们打开源码,依次打开frameworks -> base -> core -> jni -> android,如下图:

Android源码

graphicsopengl这两个就代表着Android图像处理引擎库,Skia主导,会调用opengl里面的内容进行一个原理性的绘制。
我们继续好Bitmap的native实现类,
Bitmap的native实现类

打开文件,搜我们要找的nativeCreate方法
nativeCreate方法

找到了, 那他所对应的的实现函数是什么呢,显然是Bitmap_creator,好,接下来我们找Bitmap_creator这个函数。

Bitmap_creator

找到了,那我们刚才nativeCreate方法返回的Bitmap实际上是由Bitmap_creator这个方法返回的。这里面的代码我们不需要去了解,但我们发现很多结构体是以SK开头的。那SK是什么呢,我们再来看这个Bitmap.cpp的头文件:
Bitmap.cpp

除了Android系统自带的头文件之外,有很多引用一SK开头的头文件。那SK和Skia又有什么联系呢,是不是取了Skia的的首字母呀?对的,是这样的。再继续看,我们发现真正一张图片加载实际是SkBitmap来进行实现。
SkBitmap

既然Skia在Android的系统源码里面,那肯定找得到相关的踪迹,找到了,是不是应该扣一波666。
skia源码

Android原生图片绘制流程如下:
图片源码追踪

2.渲染控件
所有的View是不是都要重写onDraw()方法啊?是的,那我们以ImageView为例去看一下它的onDraw()方法是如何实现的。
发现onDraw()方法都是通过canvas来进行绘制。
在这里插入图片描述

继续
在这里插入图片描述

在这里插入图片描述

又是调用了这么多native方法,既然和图片绘制类似,那我们就不在这看canvas.cpp了,有兴趣的可以去看一下,也是在graphics包下。
在这里插入图片描述

总结:
我们所有的图片、控件以及XML布局都是经过native来绘制,native最终又调用了Skia图像处理引擎,这也就是我们Android的界面为什么能够显示,为什么我们可以在XML去写一个布局,其实这都和Skia密不可分。同理,Flutter可以运行在IOS上,是因为Dart通过Flutter引擎调,Flutter引擎又调用了之下IOS的JEPG图像处理引擎,这样也是Flutter为什么可以实现跨平台基本原理。

题外话:Skia和JEPG有什么关系呢?其实就像Retrofit和OkHttp关系,Skia是在JEPG的基础上进行了二次封装。更进一步可以说Android和IOS其实是用的同样的图片处理引擎库。

Flutter性能优异

我们通过两张图(第一张Android原生渲染流程,第二张Flutter渲染流程)来看,可以发现Flutter较原生而言,中间环节更少,这也就意味着更加高效,可能我们写小demo时看不出什么区别来,但是随着我们项目需求的不断增加,那Flutter的优越性就越来越明显了。


在这里插入图片描述

在这里插入图片描述

其他

至于为什么选择Flutter,Flutter的发展趋势、Flutter与其他跨平台解决方案的对比,RN与Flutter的渲染对比以及Flutter的环境搭建,网上的相关资料很多且整理的十分详尽,这里不一一介绍,大家可以去查阅。

Flutter学习资料

  • Flutter文档和SDK

文档参考
https://flutter.dev
https://flutterchina.club/
SDK下载
https://github.com/flutter/flutter
https://storage.googleapis.com/flutter_infra/releases/stable/windows/flutter_windows_v1.2.1-stable.zip
https://storage.googleapis.com/flutter_infra/releases/stable/macos/flutter_macos_v1.2.1-stable.zip
https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.2.1-stable.tar.xz

下一篇文章我将对Dart基础进行汇总整理,敬请期待。