Flutter的程式碼都是預設跑在root isolate上的,負責渲染,還有UI互動。 使用場景:有耗時的任務,比如讀寫檔案、密集型計算等,需要新建一個isolate來處理,看上去類似js的Web Worker
如何建立一個isolate呢?
先看下示意圖,總共需要4步來做:
- 第一步及第二步是建立類似握手的一個過程
- 第三步和第四步是傳送資料及處理資料並返回的過程
具體示例程式碼
看程式碼前先了解幾個關鍵類:
- 使用SendPort是isolate之間的唯一通訊方式,可以傳送任何資訊。
- ReceivePort 是一個非廣播流,只能有一個監聽者,監聽後才可以收到message
對應的測試程式碼:
loadData() async {
// 通過spawn新建一個Isolate,繫結靜態方法並傳遞App端port1
print('spawn1');
ReceivePort receivePort = ReceivePort();//App端的監聽
await Isolate.spawn(dataLoader, receivePort.sendPort`);//spawn(port1)
print('spawn2');
// 獲取新Isolate端的port2
SendPort sendPort = await receivePort.first;
print('spawn3');
//把要做的任務 使用Isolate端的port2 傳遞過去
List dataList = await sendReceive(sendPort, 'https://jsonplaceholder.typicode.com/posts');//要做的具體任務,封裝成Future方法
print('spawn4');
print('dataList $dataList');
}
// Isolate端的處理方法
static dataLoader(SendPort sendPort) async {
// 建立監聽port2,並通過app端port1,回傳Isolate端的port2
ReceivePort receivePort = ReceivePort();//Isolate端的監聽
print('Loader1');
sendPort.send(receivePort.sendPort);// port1.send(port2);
print('Loader2');
// 監聽所有App端發來的訊息,並進行處理,可以傳key,引數,做區分處理等等
await for (var msg in receivePort) {
String requestURL = msg[0];
SendPort callbackPort = msg[1];// port3
print(requestURL);
print('Loader3');
/// 假設處理任務
final dataList = await Future.delayed(Duration(seconds: 5), () {
return ['sdf', 'ggg'];
});
print('Loader4');
// 回撥返回值給呼叫者
callbackPort.send(dataList);
print('Loader5');
}
}
/// 建立自己的監聽port,並且向新isolate傳送訊息
///
/// 為什麼要建立port3呢?
///
/// 因為ReceivePort是Stream,只能監聽一次,為了更好的隔離任務監聽,所以就新建了個,
/// 而且儘量每個任務都自己寫一個監聽,彼此互不影響
Future sendReceive(SendPort sendPort, String url) {
// 任務監聽器
ReceivePort receivePort = ReceivePort();
print('send1');
// 傳送要做的事情
sendPort.send([url, receivePort.sendPort]);//port2.send(tohandletask, port3);
print('send2');
// 接收到返回值,返回給呼叫者
return receivePort.first;
}
複製程式碼
上面程式碼對應的日誌如下:
flutter: spawn1
flutter: Loader1
flutter: Loader2
flutter: spawn2
flutter: spawn3
flutter: send1
flutter: send2
flutter: https://jsonplaceholder.typicode.com/posts
flutter: Loader3
flutter: Loader4
flutter: Loader5
flutter: spawn4
flutter: dataList [sdf, ggg]
複製程式碼
如有問題歡迎指正~~