1. 接口 abstract implements java 中是interface
abstract class Processor {
late String cores;
arch(String name) {}
}
abstract class Camera {
late String resolution;
brand(String name);
}
class Phone implements Processor, Camera {
@override
arch(String name) {
print(name);
}
@override
brand(String name) {
print(name);
}
@override
String cores;
@override
String resolution;
Phone()
: cores = '3',
resolution = 'name';
}
void main() {
print("hello world");
var phone = Phone();
}
2. mixin 提高代碼的復(fù)用度
- class mixin 關(guān)鍵字都可已推薦 mixin
- with 可以是多個(gè) ”,“ 分割,后面的屬性和方法重名會(huì)覆蓋前面的
- 用作混入的類不能有構(gòu)造函數(shù)
- mixin 類只能繼承 Object
// class mixin
class MixinA {
String name = 'MixinA';
void showInfo() {
print(name);
}
}
mixin MixinB {
// MixinB(); 用作混入的類不能有構(gòu)造函數(shù)
String name = 'MixinB';
void showInfo() {
print(name);
}
}
class MixinTest with MixinA, MixinB {}
void main() {
print("hello world");
var mixinTest = MixinTest();
print(mixinTest.name);
}
3. extension 擴(kuò)展
//擴(kuò)展內(nèi)置類
extension StringExt on String {
int parseInt() {
return int.parse(this);
}
}
//擴(kuò)展自定義類
class Person {
final String name;
Person(this.name);
}
extension PersonExt on Person {
info() {
print(this.name);
}
}
4. call
在類中可以聲明call 方法
-
類的實(shí)例當(dāng)做行數(shù)使用
void main(List<String> args) { var phone = Phone();//將類的實(shí)例當(dāng)做函數(shù)使用 phone('18614060661'); } class Phone { call(String num) { print('phone number is $num'); } }
5. noSuchMethod
class Person {
final String name;
Person(this.name);
@override
noSuchMethod(Invocation invocation) {
return super.noSuchMethod(invocation);
}
}
void main(List<String> args) {
//dynamic 修飾
dynamic p = Person('zhu');
p.say();
}
6. hashCode
- dart 對(duì)象的唯一標(biāo)識(shí)
- 表現(xiàn)為一串?dāng)?shù)字 // eg: obj.hashCode; 608635269
- 可以判斷兩個(gè)對(duì)象是否是同一個(gè)內(nèi)存地址
7. typedef
- 自定義別名
- 語法
- typedef function_name (parmas)
- typedef variable_name=List<int> (dart:2.13之后)
typedef MathOperation = Function(int a, int b);
fn1(int a, b) {
return a + b;
}
void main(List<String> args) {
if (fn1 is MathOperation) {
print('true');
} else {
print('false');
}
}
8.eventLoop 事件輪詢機(jī)制


9 isolate
- isolate 是dart 中的線程
- 每個(gè)isolate都有自己的獨(dú)立的私有內(nèi)存(多個(gè)isolate不共享內(nèi)存)
- dart中的線程是以 隔離(isolate)的方式存在
- 沒有共享沒存,不存在資源競爭(不需要鎖,也就沒有死鎖)
- 所有dart 都運(yùn)行在isolate中
- isolate 提供了dart | flutter 的運(yùn)行環(huán)境
- 微任務(wù)隊(duì)列、事件隊(duì)列、事件輪詢 都在isolate 中進(jìn)行
- 多線程長用來解決耗時(shí)較長的異步任務(wù)
- isolate的位置

9.1 isolate 多線程-創(chuàng)建
-
Isolate 類 用來管理線程(創(chuàng)建、暫停、殺死 Isolate線程)
Isolate.spawn();//創(chuàng)建線程 Isolate.spawnUri();//跨文件 函數(shù)創(chuàng)建線程 Isolate.pause();//暫停 Isolate.kill();//殺死
import 'dart:isolate';
/*
entryPoint : 必須是一個(gè)頂層方法或靜態(tài)方法
message:
1. dart 原始類型 eg:null,int,String ...
2. SendPort 實(shí)例 ReceivePort().sendPort
3. 包含 1 和 2 的list、 map 可以嵌套
*/
static Future<Isolate> spawn<T>(void entryPoint(T message), T message);
import 'package:flutter/foundation.dart'
compute();
-
使用實(shí)例1:創(chuàng)建一個(gè)線程
import 'dart:isolate'; void main() { test(); } void test() async { print('---start---'); print('thead: ${Isolate.current.debugName}'); Isolate.spawn(newThread1, 'zhu'); //一般 異步執(zhí)行 print('---end---'); /* end 和 子線程打印順序不固定 ---start--- thead: main ---end--- thead: newThread1 message:zhu ---start--- thead: main thead: newThread1 message:zhu ---end--- */ } void newThread1(dynamic message) { print('thead: ${Isolate.current.debugName} message:$message'); }
-
實(shí)例2 創(chuàng)建多個(gè)線程
import 'dart:isolate'; void main(List<String> args) { test(); } void test() async { print('---start---'); print('thead: ${Isolate.current.debugName}'); Isolate.spawn(newThread1, 'zhu'); Isolate.spawn(newThread2, true); Isolate.spawn(newThread3, 1000); print('---end---'); } void newThread1(dynamic message) { print('thead: ${Isolate.current.debugName} message:$message'); } void newThread2(dynamic message) { print('thead: ${Isolate.current.debugName} message:$message'); } void newThread3(dynamic message) { print('thead: ${Isolate.current.debugName} message:$message'); }
9.2 多線程通信機(jī)制-Port
isolate 多線程之間通信的唯一方式是 Port
ReceivePort 類,初始化接受端口,創(chuàng)建發(fā)送端口,接受消息、監(jiān)聽消息、關(guān)閉端口
SendPort 類 將消息發(fā)送給ReceivePort
-
通信方式
- 單項(xiàng)通信:A -> B
- 雙向通信:A <-> B
- image.png
import 'dart:isolate';
void main(List<String> args) {
test();
}
test() {
print('---start---');
print(Isolate.current.debugName);
//創(chuàng)建接收端口
ReceivePort receivePort = ReceivePort();
//建立監(jiān)聽
receivePort.listen((message) {
print('listen: $message');
//關(guān)閉監(jiān)聽
receivePort.close();
});
//獲取發(fā)送端口
SendPort sendPort = receivePort.sendPort;
Isolate.spawn(mutilThead, sendPort);
print('---end---');
}
void mutilThead(message) {
print(Isolate.current.debugName);
print(message);
SendPort sendPort = message as SendPort;
sendPort.send('mutilThead 發(fā)來的消息');
}

import 'dart:isolate';
void main(List<String> args) async {
print('---start---');
print(Isolate.current.debugName);
//創(chuàng)建接收端口
ReceivePort r1 = ReceivePort();
//建立監(jiān)聽
//獲取發(fā)送端口
SendPort p1 = r1.sendPort;
Isolate.spawn(newThead, p1);
SendPort p2 = await r1.first;
var msg = await sendToReceive(p2, 'hello');
print('主線程接收到:$msg');
print('---end---');
}
Future sendToReceive(SendPort sendPort, dynamic msg) async {
print('${Isolate.current.debugName} 發(fā)送消息: $msg');
ReceivePort receivePort = ReceivePort();
sendPort.send([receivePort.sendPort, msg]);
return receivePort.first;
}
void newThead(SendPort p1) async {
var r2 = ReceivePort();
p1.send(r2.sendPort);
await for (var msg in r2) {
var data = msg[1];
print('新線程收到了主線程的消息:$data');
SendPort replyPort = msg[0];
//回復(fù)消息
replyPort.send('子線程答復(fù)->$data');
}
}
/*
---start---
main
main 發(fā)送消息: hello
新線程收到了主線程的消息:hello
主線程接收到:子線程答復(fù)->hello
---end---
*/
-
Isolate.spawnUri
import 'dart:isolate'; void main(List<String> args) { print('start'); newIsolate(); print('end'); } void newIsolate() async { ReceivePort r1 = ReceivePort(); SendPort p1 = r1.sendPort; var childThead = await Isolate.spawnUri( Uri(path: 'child_isolate.dart'), ['data1', 'data2', 'data3'], p1); r1.listen((message) { print('主線程收到消息:$message'); if (message[0] == 0) { print('加載中'); } else if (message[0] == 1) { print('處理中'); } else if (message[0] == 2) { print('初始完成'); r1.close(); childThead.kill(); } }); }//child_isolate.dart import 'dart:io'; import 'dart:isolate'; void main(List<String> args, SendPort p1) { print('${Isolate.current.debugName} 收到:$args'); p1.send([0, '加載中']); sleep(Duration(seconds: 1)); p1.send([1, '處理中']); sleep(Duration(seconds: 1)); p1.send([2, '處理完成']); }
10.Future (類似js 中的Promise)
10.1初始
-
概念
Future 是dart 中的類,我們可以通過Future 實(shí)例封裝一些異步任務(wù)
Future 含義是未來。未來要執(zhí)行的任務(wù)可以放到Future中
-
Future 的三種狀態(tài)
- 未完成 (Uncompleted)
- 已完成,并返回?cái)?shù)據(jù)(Complete with data)
- 已完成,但返回錯(cuò)誤(Complete with error)
-
獲取實(shí)例
-
自動(dòng)返回
- final myFuture = http.get('http://xxxx')
- final myFuture = SharePreferences.getInstace;
-
手動(dòng)創(chuàng)建
- final myFuture = Future((){return 123;});
- final myFuture = Future.error(Exception());
- Final myFuture = Future.delayed(Duration(seconds:3),(){return 123;});
-
-
狀態(tài)相關(guān)方法
- 創(chuàng)建
- Uncomplete
- then()
- Complate with data
- catchError()
- Complate with error
- whenComplate()
- Complate with data + Complate with error
- 創(chuàng)建
void main(List<String> args) {
test();
}
void test() {
print('start');
var myFuture = Future.delayed(Duration(seconds: 3), () {
throw '異常數(shù)據(jù)';
});
myFuture.then((value) => print(value)).catchError((error) {
print('error : ' + error);
}, test: (error) => error.runtimeType == String).whenComplete(
() => print('complate'));
print('end');
}
/*
start
end
error : 異常數(shù)據(jù)
complate
*/
10.2 Future執(zhí)行順序
Future 默認(rèn)是異步任務(wù),會(huì)被丟到事件隊(duì)列(event queue)中
-
Future.sync()
- 同步任務(wù),同步執(zhí)行(不會(huì)丟到異步隊(duì)列)
-
Future.microtast()
- 微任務(wù)丟到microtask queue 中優(yōu)先級(jí)比event queue 高
-
Future.value(val)
val 是常量 (等同microtask)
val 是異步(按照異步任務(wù)處理)
10.3 多任務(wù)
Future.any(Futures) 返回最先完成的Future結(jié)果
Future.wait(Futures) 等待所有的Future完成,并返回所有Future的結(jié)果
Future.doWhile(action) 按照條件遍歷執(zhí)行多個(gè)Future
Future.forEach(elements,action) 遍歷一個(gè)給定的集合,根據(jù)集合元素執(zhí)行多個(gè)Future
10.4. FutureBuilder - snapshot
- snapshot.connectionState
- ConnectionState.none (未連接異步任務(wù))
- ConnectionState.waiting (連接異步任務(wù),等待交互)
- ConnectionState.active (連接異步任務(wù),正在交互)
- ConnectionState.done (異步任務(wù)完成)
snapshot.hasData
snapshot.hasError
11.Stream
11.1 Stream 概念
Stream 是Dart 中異步數(shù)據(jù)流,可以連續(xù)不斷地返回多個(gè)數(shù)據(jù)。
- Future是異步 ,單只返回一個(gè)值
- Stream也是異步,可以返回多個(gè)值(數(shù)據(jù)流)
Stream 相關(guān)的API
- 通過listen進(jìn)行數(shù)據(jù)監(jiān)聽
- 通過error 接受失敗狀態(tài)
- done來接收結(jié)束狀態(tài)
11.2 Stream 類型
Single-Subscription (單一訂閱)
- 數(shù)據(jù)流只能listen 一次(listen 多次會(huì)報(bào)錯(cuò))
- StreamController().stream
- Stream stream = Stream.fromIterable(data)
import 'dart:async';
void main(List<String> args) {
//創(chuàng)建一次訂閱數(shù)據(jù)流控制器
StreamController streamController = StreamController();
//一次監(jiān)聽 只能監(jiān)聽一次
streamController.stream.listen((event) {
print('接收到數(shù)據(jù):$event');
});
//sink數(shù)據(jù)槽 添加數(shù)據(jù)
streamController.sink.add('123');
streamController.sink.add('abc');
/*
接收到數(shù)據(jù):123
接收到數(shù)據(jù):abc
*/
}
Broadcase (廣播)
- 數(shù)據(jù)流可以被 listen 多次
- StreamController<int>.broadcast();
- stream.asBroadcastStream()
import 'dart:async';
void main(List<String> args) {
//創(chuàng)建多次訂閱數(shù)據(jù)流控制器
StreamController streamController = StreamController.broadcast();
streamController.stream.listen((event) {
print('第一次監(jiān)聽接收到數(shù)據(jù):$event');
});
//sink數(shù)據(jù)槽 添加數(shù)據(jù)
streamController.sink.add('123');
streamController.stream.listen((event) {
print('第二次監(jiān)聽接收到數(shù)據(jù):$event');
});
streamController.sink.add('abc');
/*
第一次監(jiān)聽接收到數(shù)據(jù):123
第二次監(jiān)聽接收到數(shù)據(jù):abc
第一次監(jiān)聽接收到數(shù)據(jù):abc
*/
}
11.3 創(chuàng)建 Stream 實(shí)例
StreamController 類
- sink
- stream
Stream 類
- Stream.fromFuture();
- Stream.fromFutures();
- Stream.fromIterable();
- Stream.periodic();
Future<String> getFuture() async {
await Future.delayed(Duration(seconds: 2), () {});
return DateTime.now().toString();
}
void main(List<String> args) async {
Stream.fromFuture(getFuture()).listen((event) {
print('fromFuture 接收到數(shù)據(jù) : $event');
}, onDone: () {
print('fromFuture onDone');
});
Stream.fromFutures([getFuture(), getFuture(), getFuture()]).listen((event) {
print('fromFutures 接收到數(shù)據(jù) : $event');
});
Stream.fromIterable([123, 'acb', null]).listen((event) {
print('fromIterable 接收到數(shù)據(jù) : $event');
});
}
/*
fromIterable 接收到數(shù)據(jù) : 123
fromIterable 接收到數(shù)據(jù) : acb
fromIterable 接收到數(shù)據(jù) : null
fromFuture 接收到數(shù)據(jù) : 2022-09-21 23:01:08.346103
fromFuture onDone
fromFutures 接收到數(shù)據(jù) : 2022-09-21 23:01:08.355317
fromFutures 接收到數(shù)據(jù) : 2022-09-21 23:01:08.355797
fromFutures 接收到數(shù)據(jù) : 2022-09-21 23:01:08.355834
*/
Stream.periodic();
void main(List<String> args) {
// Stream.periodic(Duration(seconds: 1), (int data) => data).listen((event) {
// print('收到數(shù)據(jù):$event'); //收到數(shù)據(jù):null
// });
Stream.periodic(Duration(seconds: 1), (int data) => data).take(5) //接收5次數(shù)據(jù)
.listen((event) {
print('收到數(shù)據(jù):$event');
}, onDone: () => print('periodic done'));
/*
收到數(shù)據(jù):0
收到數(shù)據(jù):1
收到數(shù)據(jù):2
收到數(shù)據(jù):3
收到數(shù)據(jù):4
periodic done
*/
}
11.4 Stream 操作
take(int count) | takeWhile() 取count次
where()
distinct() //去重 去掉和前一個(gè)數(shù)據(jù)相同的數(shù)據(jù)(連續(xù)重復(fù)值)
skip(int count) | skipWhile() 跳過count個(gè)
map()
toSet() | toList() | toString()
length | first | last
.... 等等
12.Generator(生成器)
概念:生成器是有一種特殊的函數(shù),返回值通過yield 關(guān)鍵詞來指定
分類
-
同步生成器(sync + yield),yield==return + continue
- 使用 sync* ,返回是Iterable 對(duì)象
- yeild 會(huì)返回moveNext為true,并等待moveNext指令
-
異步生成器(async + yield)
- 使用 async* ,返回是Stream 對(duì)象
- yeild不用暫停,數(shù)據(jù)以流的方式一次性推送
-
遞歸生成器 (yeild*)
- yeild* 是指針,指向遞歸函數(shù)
同步生成器(sync + yield)
void main(List<String> args) {
var nums = getNumber(5).iterator;
while (nums.moveNext()) {
print(nums.current);
}
}
Iterable<int> getNumber(int n) sync* {
print('start');
var i = 0;
while (i < n) {
yield i++;
}
print('end');
/*
start
0
1
2
3
4
end
*/
}
異步生成器(async + yield)
void main(List<String> args) {
print('start');
var stream = getNumbers(5);
stream.listen((event) {
print('接收到數(shù)據(jù):$event');
}, onDone: () {
print('done');
});
print('end');
/*
start
end
接收到數(shù)據(jù):0
接收到數(shù)據(jù):1
接收到數(shù)據(jù):2
接收到數(shù)據(jù):3
接收到數(shù)據(jù):4
done
*/
}
Stream<int> getNumbers(int n) async* {
var i = 0;
while (i < 5) {
yield i++;
}
}
遞歸生成器 (yeild*)
void main(List<String> args) {
print('start');
var res = getRange(1, 5);
res.forEach((element) {
print(element);
});
print('end');
}
Iterable<int> getRange(int start, int end) sync* {
if (start <= end) {
yield start;
// for (var j in getRange(start + 1, end)) {
// yield j;
// } //等價(jià)寫法
yield* getRange(start + 1, end);
}
/*
start
1
2
3
4
5
end
*/
}
