由于Android和ios本身的差异性,想要开发跨平台的app不是件容易的是,目前市面上的解决方案,如React native ,基于 WebView 的 Cordova、AppCan 等,都不能很好地满足功能和性能的需求,直到去年听说了Google官方推出的跨平台UI框架Flutter,当时好奇去尝试写了个demo,意外觉得非常好用,对比与原生的app开发流程,省去了大量繁琐的初始配置还有一些工具的封装,因为Flutter已经考虑好了这些问题,让你能够专注于UI和逻辑业务的开发,这次的学习笔记会主要记录一些Flutter的概览,简单的原理和对比其他跨平台方案的优缺点。
Flutter是什么?为什么谷歌要推出它
简单说就是谷歌为了一套代码跑两个系统(IOS和Android)而推出的一个东西,可以大大节省开发和维护成本,其实不止移动端,今年开发者大会又宣布了支持前端和桌面端,还有未来的物联网设备,目前使用Flutter的代表有阿里巴巴的闲鱼, 先看看官方给出的Flutter的框架
其中 Framework层运行在Flutter Engine上,Engine相当于是Flutter的独立虚拟机,由它来提供适配及其跨平台;所以Flutter不使用移动端系统的原生控件, 而是使用自己的 Engine 来绘制 Widget (Flutter的显示单元);
其中几个重要的
Dart:flutter开发语言,这也是谷歌自己的....比较冷门,通过 AOT 编译为平台的原生代码,Framework层全部由dart编写,有Material和Cupertino两种风格的UI对应Android和iOS
Skia:这是谷歌自己的2D图形处理库,被应用于自家的Chrome浏览器,Engine的绘图核心
Widgets:Flutter的显示单元,“一切皆为Widget”是flutter的理念,跟前端的组件化比较接近,与原生的控件有点差异,每个widgets有一个state用来储存状态,像MVVM架构
flutter的优势在哪
高性能,跟目前市面上的跨平台方案比,甩了几条街
Fluttr对比RN,RN是使用前端代码写出UI,然后由框架生成原生的代码,中间多了一层桥接
而Flutter的原理在于,
- UI只使用原生的绘图接口,基于图像引擎直接去绘制Ui,而这个绘图过程就是上文提到的Skia,
- Flutter引擎是由C++编写的,拥有低延迟输入以及高帧速率,
- 使用Dart语言AOT编译为本地代码,有一定的效率加成
直接上代码
语法都大同小异,先看一看语言风格,第一印象:很像前端,全是组件
class _SampleAppPageState extends State<SampleAppPage> {
// Default placeholder text
String textToShow = "I Like Flutter";
void _updateText() {
setState(() {
// update the text
textToShow = "Flutter is Awesome!";
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sample App"),
),
body: Center(child: Text(textToShow)),
floatingActionButton: FloatingActionButton(
onPressed: _updateText,
tooltip: 'Update Text',
child: Icon(Icons.update),
),
);
}
}
以上代码就是App的一个界面,是不是很简单,如果是Android的话,先要去注册一个Activity,然后再编写一个Activity和一个xml布局代码,而Flutter直接一个类就搞定了
下面是一个简单的Widget,可以和其他的Widget组成新的Widget
import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget {
MyAppBar({this.title});
// Widget子类中的字段往往都会定义为"final"
final Widget title;
@override
Widget build(BuildContext context) {
return new Container(
height: 56.0, // 单位是逻辑上的像素(并非真实的像素,类似于浏览器中的像素)
padding: const EdgeInsets.symmetric(horizontal: 8.0),
decoration: new BoxDecoration(color: Colors.blue[500]),
// Row 是水平方向的线性布局(linear layout)
child: new Row(
//列表项的类型是 <Widget>
children: <Widget>[
new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null, // null 会禁用 button
),
// Expanded expands its child to fill the available space.
new Expanded(
child: title,
),
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
);
}
}
class MyScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Material 是UI呈现的“一张纸”
return new Material(
// Column is 垂直方向的线性布局.
child: new Column(
children: <Widget>[
new MyAppBar(
title: new Text(
'Example title',
style: Theme.of(context).primaryTextTheme.title,
),
),
new Expanded(
child: new Center(
child: new Text('Hello, world!'),
),
),
],
),
);
}
}
void main() {
runApp(new MaterialApp(
title: 'My app', // used by the OS task switcher
home: new MyScaffold(),
));
}
在Android中经常需要监听生命周期事件,而在Flutter中就可以通过挂接到WidgetsBinding观察并监听didChangeAppLifecycleState更改事件来监听生命周期事件,一共有4种状态
- resumed - 应用程序可见并响应用户输入。这是来自Android的onResume
- inactive - 应用程序处于非活动状态,并且未接收用户输入。此事件在Android上未使用,仅适用于iOS
- paused - 应用程序当前对用户不可见,不响应用户输入,并在后台运行。这是来自Android的暂停
- suspending - 该应用程序将暂时中止。这在iOS上未使用
(来自官网)可以看到对Android和IOS的生命周期做了整合,但相比于原生的,还是少了很多事件。
需要一提的是,Android中的Fragment在Flutter中并不存在,查阅官方说明给出的答复是这样:
在Android中,Activity代表用户可以完成的一项重点工作。Fragment代表了一种模块化代码的方式,可以为大屏幕设备构建更复杂的用户界面,可以在小屏幕和大屏幕之间自动调整UI。 在Flutter中,这两个概念都等同于Widget。
然后在学习过程中,也发现了其他的一些问题,比如一些硬件的支持,访问相机,地图API等都不太完善,但已经有许多插件可以选择,可是毕竟是新出的系统,还是不够成熟,整个行业的生态也没有建立起来。
再说一下自己对Flutter的看法,之前在学习Flutter的途中听说了谷歌的新系统Fuchsia的消息,后来查阅了一些资料,发现Fuchsia是钦定了Flutter和Dart作为其官方的开发平台和语言,Fuchsia是谷歌的下一个Android(由于Android碎片化过于严重,对跨平台应用也不友好,还有比如jvm的性能问题,java不是自己的语言会吃官司等等一系列的问题导致谷歌有理由呢研发下一代系统)在移动端,pc,网页端,物联网终端设备上都可以运行,因此我认为谷歌在目前这个阶段强推Flutter的原因就是他们想要让开发者使用Flutter和dart语言开发移动端的应用,建立起来自己的生态,巩固技术堡垒(全用自家的东西,总没人再来告我了吧),然后等到Fuchsia真正面世的时候,现有的Flutter应用可以直接运行在新系统上,一定程度上实现了对Android的“兼容”,所以我认为目前的Flutter开发前景是不错的,就算把它单纯地当成一种跨平台UI方案,也算是优秀的了。