目录

  • Flutter介绍
    • 跨平台技术简介
      • 1. 跨平台自绘引擎
      • 2. 高性能
    • Flutter 为什么选择 Dart 语言?
      • 1.开发效率高。
      • 2.高性能。
      • 3.快速内存分配。
      • 4.类型安全和空安全。
      • 5.Dart 团队就在你身边。
    • Flutter框架结构
  • Dart语言简介
    • 1.变量声明
      • var
      • dynamic与Object
      • final 或 const
      • 空安全(null-safety)
    • 2.函数
    • 3.异步支持
      • Future.then
      • Future.catchError和onError
      • Future.whenComplete
      • Future.wait
      • async/await
      • Stream

Flutter介绍

纯原生开发主要面临动态化更新和开发成本两个问题,而针对这两个问题,诞生了一些跨平台的动态化框架

跨平台技术简介


Flutter 是 Google 推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOS 和 Android平台

1. 跨平台自绘引擎

Flutter 既不使用 WebView,也不使用操作系统的原生控件。 相反,Flutter 使用自己的Skia来绘制 Widget(组件)。这样不仅可以保证在 Android 和iOS 上 UI 的一致性,也可以避免对原生控件依赖而带来的限制及高昂的维护成本。

目前 Google Chrome浏览器和 Android 均采用 Skia 作为其 2D 绘图引擎。

目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux、Fuchsia(Google新的自研操作系统)等众多平台

2. 高性能

Flutter APP 采用 Dart 语言开发。Dart 在 JIT(即时编译)模式下,执行速度与 JavaScript 基本持平。但是 Dart 支持 AOT,当以 AOT模式运行时,JavaScript 便远远追不上了

Flutter 使用自己的渲染引擎来绘制 UI ,布局数据等由 Dart 语言直接控制,所以在布局过程中不需要像 RN 那样要在 JavaScript 和 Native 之间通信

Flutter 为什么选择 Dart 语言?

1.开发效率高。

Flutter 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;

Flutter 在发布时可以通过 AOT 生成高效的机器码以保证应用性能。而 JavaScript 则不具有这个能力。

2.高性能。

Flutter 旨在提供流畅、高保真的的 UI 体验,而 Dart 支持 AOT,在这一点上可以做的比 JavaScript 更好。

3.快速内存分配。

Flutter 框架使用函数式流,这使得它在很大程度上依赖于底层的内存分配器,而 Dart 也正好满足。

4.类型安全和空安全。

由于 Dart 是类型安全的语言,所以 Dart 支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题。

5.Dart 团队就在你身边。

由于有 Dart 团队的积极投入,Flutter 团队可以获得更多、更方便的支持Dart VM 之前已经针对吞吐量进行了优化,但团队现在正在优化 VM 的延迟时间,这对于 Flutter 的工作负载更为重要。

Flutter框架结构


Flutter 从上到下可以分为三层:框架层、引擎层和嵌入层

框架层:纯 Dart实现的 SDK,它实现了一套基础库

引擎层:主要是 C++ 实现,包括 Skia 引擎、Dart 运行时、文字排版引擎等

嵌入层:嵌入层采用了当前平台的语言编写,例如 Android 使用的是 Java 和 C++, iOS 和 macOS 使用的是 Objective-C 和 Objective-C++,Windows 和 Linux 使用的是 C++

Flutter 代码可以通过嵌入层,以模块方式集成到现有的应用中,也可以作为应用的主体

Dart语言简介

1.变量声明

var

Dart 中 var 变量一旦赋值,类型便会确定,则不能再改变其类型

var t = "hi world";
// 下面代码在dart中会报错,因为变量t的类型已经确定为String,
// 类型一旦确定后则不能再更改其类型。
t = 1000;

dynamic与Object

dynamic与Object声明的变量都可以赋值任意对象,且后期可以改变赋值的类型,不同的是dynamic声明的对象编译器会提供所有可能的组合,而Object声明的对象只能使用 Object 的属性与方法, 否则编译器会报错

dynamic a;Object b = "";main() {a = "";printLengths();}   printLengths() {// 正常
print(a.length);// 报错 The getter 'length' is not defined for the class 'Object'print(b.length);}

final 或 const

不可更改变量,使用 final 或 const,两者区别在于:const 变量是一个编译时常量(编译时直接替换为常量值),final变量在第一次使用时被初始化。被final或者const修饰的变量,变量类型可以省略

//可以省略String这个类型声明
final str = "hi world";
//final String str = "hi world";
const str1 = "hi world";
//const String str1 = "hi world";

空安全(null-safety)

int i = 8; //默认为不可空,必须在定义时初始化。
int? j; // 定义为可空类型,对于可空变量,我们在使用前必须判空。// 如果我们预期变量不能为空,但在定义时不能确定其初始值,则可以加上late关键字,
// 表示会稍后初始化,但是在正式使用它之前必须得保证初始化过了,否则会报错
late int k;
k=9;

2.函数

Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,函数返回值没有类型推断,函数可作为变量,可作为参数

device是可选参数

String say(String from, String msg, [String? device]) {}

使用{param1, param2, …},放在参数列表的最后面,用于指定命名参数

void enableFlags({bool bold, bool hidden}) {// ...
}

调用

enableFlags(bold: true, hidden: false);

Dart 是不支持多继承的,但是它支持 mixin,简单来讲 mixin 可以 “组合” 多个类

定义了几个 mixin,然后通过 with 关键字将它们组合成不同的类。有一点需要注意:如果多个mixin 中有同名方法,with 时,会默认使用最后面的 mixin 的

class Person {say() {print('say');}
}mixin Eat {eat() {print('eat');}
}mixin Walk {walk() {print('walk');}
}mixin Code {code() {print('key');}
}class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

3.异步支持

Dart类库有非常多的返回Future或者Stream对象的函数。 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作。而不是等到这个操作完成。

async和await关键词支持了异步编程,允许您写出和同步代码很像的异步代码

Future.then

2秒后返回结果字符串"hi world!",然后我们在then中接收异步结果并打印结果

Future.delayed(Duration(seconds: 2),(){return "hi world!";
}).then((data){print(data);
});

Future.catchError和onError

异步任务发生错误,我们可以在catchError中捕获错误

Future.delayed(Duration(seconds: 2),(){//return "hi world!";throw AssertionError("Error");
}).then((data){//执行成功会走到这里  print("success");
}).catchError((e){//执行失败会走到这里  print(e);
});//或者onError
Future.delayed(Duration(seconds: 2), () {//return "hi world!";throw AssertionError("Error");
}).then((data) {print("success");
}, onError: (e) {print(e);
});

Future.whenComplete

无论异步任务执行成功或失败都需要做一些事的场景,比如在网络请求前弹出加载对话框,在请求结束后关闭对话框。这种场景,有两种方法,
第一种是分别在then或catch中关闭一下对话框,
第二种就是使用Future的whenComplete回调

Future.delayed(Duration(seconds: 2),(){//return "hi world!";throw AssertionError("Error");
}).then((data){//执行成功会走到这里 print(data);
}).catchError((e){//执行失败会走到这里   print(e);
}).whenComplete((){//无论成功或失败都会走到这里
});

Future.wait

等待多个异步任务都执行结束后才进行一些操作,比如我们有一个界面,需要先分别从两个网络接口获取数据,获取成功后,我们需要将两个接口数据进行特定的处理后再显示到UI界面上

//只有数组中所有Future都执行成功后,才会触发then的成功回调,只要有一个Future执行失败,就会触发错误回调
Future.wait([// 2秒后返回结果  Future.delayed(Duration(seconds: 2), () {return "hello";}),// 4秒后返回结果  Future.delayed(Duration(seconds: 4), () {return " world";})
]).then((results){print(results[0]+results[1]);
}).catchError((e){print(e);
});

async/await

Dart中的async/await 和JavaScript中的async/await功能是一样的:异步任务串行化

如果代码中有大量异步逻辑,并且出现大量异步任务依赖其他异步任务的结果时,必然会出现Future.then回调中套回调情况。

比如现在有个需求场景是用户先登录,登录成功后会获得用户ID,然后通过用户ID,再去请求用户个人信息,获取到用户个人信息后,为了使用方便,我们需要将其缓存在本地文件系统,代码如下:

//先分别定义各个异步任务
Future<String> login(String userName, String pwd){...//用户登录
};
Future<String> getUserInfo(String id){...//获取用户信息
};
Future saveUserInfo(String userInfo){...// 保存用户信息
};
login("alice","******").then((id){//登录成功后通过,id获取用户信息    getUserInfo(id).then((userInfo){//获取用户信息后保存 saveUserInfo(userInfo).then((){//保存用户信息,接下来执行其他操作...});});
})

这个问题被形象的称为回调地狱

消除回调地狱
一、使用Future消除Callback Hell

login("alice","******").then((id){return getUserInfo(id);
}).then((userInfo){return saveUserInfo(userInfo);
}).then((e){//执行接下来的操作
}).catchError((e){//错误处理  print(e);
});

Future 的所有API的返回值仍然是一个Future对象,所以可以很方便的进行链式调用” ,如果在then 中返回的是一个Future的话,该future会执行,执行结束后会触发后面的then回调,这样依次向下,就避免了层层嵌套

二、使用 async/await 消除 callback hell
通过Future回调中再返回Future的方式虽然能避免层层嵌套,但是还是有一层回调,有没有一种方式能够让我们可以像写同步代码那样来执行异步任务而不使用回调的方式?答案是肯定的,这就要使用async/await了

task() async {try{String id = await login("alice","******");String userInfo = await getUserInfo(id);await saveUserInfo(userInfo);//执行接下来的操作   } catch(e){//错误处理   print(e);   }
}

Stream

Stream 也是用于接收异步事件数据,和 Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。 Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等

Stream.fromFutures([// 1秒后返回结果Future.delayed(Duration(seconds: 1), () {return "hello 1";}),// 抛出一个异常Future.delayed(Duration(seconds: 2),(){throw AssertionError("Error");}),// 3秒后返回结果Future.delayed(Duration(seconds: 3), () {return "hello 3";})
]).listen((data){print(data);
}, onError: (e){print(e.message);
},onDone: (){});

输出

I/flutter (17666): hello 1
I/flutter (17666): Error
I/flutter (17666): hello 3

Flutter(一)介绍、Dart语言简介相关推荐

  1. 给Java开发者的Flutter开发基础---Dart语言

    接近半年没有在简书冒泡了.这段时间一是忙于使用云信IM开发相应项目,二是整理和收集相关Flutter的相关资料进行学习.国内关于Flutter的资料还是太过于稀少,以至于我只能去YouTube和Ude ...

  2. Flutter学习之Dart语言注释

    文章目录 1.单行注释 2.多行注释 3.文档注释 高效Dart注释 注释 注释句子化 避免使用块注释 文档注释 使用 /// 注释成员和类型 优先为public的接口编写注释 考虑写一个库级别的文档 ...

  3. Flutter获取随机数 Dart语言核心基础

    也许你迷茫,但是我想说,在你迷茫的同时,保持本心,过好今天就好. 学习Dart语言,首先我们需要使用到一个语言调试工具 DartPad 在 Dart 中,dart:math 类库提供了 数学常数和函数 ...

  4. 算数运算符与关系运算符_【Flutter 110】Flutter手把手教程Dart语言——运算符

    运算符 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号.Dart语言内置了丰富的运算符,并提供了以下类型的运算符:「算术运算符.关系运算符.类型判断运算符.赋值运算符.逻辑运算符.按位和移位运算 ...

  5. 类的初始化列表_【Flutter 111】Flutter手把手教程Dart语言——类、类的的成员变量和方法、类的构造函数...

    类 Dart是一种面向对象的语言,所有对象都是一个类的实例,而所有的类都继承自Object类.每个除了Object类之外的类都只有一个超类,一个类的代码可以在其它多个类继承中重复使用. 类的实例变量 ...

  6. Flutter开发准备工作dart语言

    1.装flutter sdk,下载对应版本安装即可,配对应环境变量: 2.flutter如果不带dart sdk的话,需要下载dart sdk,配对应环境变量: 3.安装Android studio, ...

  7. python语言介绍-Python语言简介

    一.Python语言发展史 1989年吉多·范罗苏姆(Guido van Rossum)中文外号"龟叔",圣诞节期间开始编写Python语言的编译器. Python这个名字,来自G ...

  8. flutter 应用场景_【Flutter 1-12】Flutter手把手教程Dart语言——什么是泛型和泛型的使用场景...

    泛型 如果你查看数组的API文档,你会发现数组List的实际类型为List.<> 符号表示数组是一个泛型(或参数化类型)通常使用一个字母来代表类型参数,比如E.T.S.K 和 V 等等. ...

  9. Flutter学习之Dart语言基础(内置类型)

    Dart支持以下内置类型: numbers strings booleans lists (也称为数组) sets maps runes (用于在字符串中表示Unicode字符) symbols Nu ...

最新文章

  1. php偶尔500,python – 偶尔500错误
  2. java nextline_Java编程语言基础的9根支柱
  3. 吴文俊AI最高成就奖颁给清华张钹院士,之前曾空缺七年
  4. Python: logging日志模块简单示例
  5. 如何通过 C# 判断某个 IP 是否属于某IP段?
  6. windows server 启用 vss_windows服务器常用的安全加固方法
  7. 湖北大学数学与计算机科学学院,2017年湖北大学数学与计算机科学学院811数据结构考研题库...
  8. Shell 操作(一)
  9. java基础:13.2 集合框架 - LinkedList、Queue
  10. react-demo
  11. 跟着迪哥学python电子书pdf-跟着迪哥学Python数据分析与机器学习实战
  12. 图片计算景深matlab程序,在线景深计算器
  13. 电脑复制,电脑复制粘贴,详细教您电脑不能复制粘贴怎么办
  14. 2020计算机视觉会议地点,2020年计算机视觉与信息技术国际会议(CVIT 2020)
  15. 《牛奶可乐经济学》读书笔记
  16. 帝国CMS[!--onclick--]标签动态显示页面点击数,解决刷新页面浏览量无变化的问题
  17. 【赶紧收藏】福利:Python全国计算机二级等级考试题库免费送!!!!
  18. Obsidian Windows同步到iCloud 再到ipad 云盘 我的电脑导航栏无法应用的问题
  19. uip-udp-demo分析---基于contiki
  20. 复旦大学研究生机试(2019)

热门文章

  1. bt分析之bt种子发布---做种(2)
  2. 推荐 6 个上周 火火火 的开源项目
  3. java怎么输出保留两位小数_剖析Java输出怎么保留两位小数
  4. “中信碳账户”开户量突破350万,发布首支低碳生活主题音乐故事片
  5. 【2023/05/13】NP完备
  6. 3ds Max人物女性角色模型建模教程
  7. 【ES实战】ES分词器介绍
  8. 二分类的评价指标总结
  9. 实现医生工作站的病历模板功能的代码(十)
  10. 国庆连夜测试羊了个羊,发现了一些游戏Bug