Flutter(一)介绍、Dart语言简介

发布时间:2025-12-09 21:35:17 浏览次数:4

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);});//或者onErrorFuture.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 1I/flutter (17666): ErrorI/flutter (17666): hello 3
需要做网站?需要网络推广?欢迎咨询客户经理 13272073477