Flutter的代碼都是默認跑在root isolate上的,負責渲染,還有UI交互。 使用場景:有耗時的任務,好比讀寫文件、密集型計算等,須要新建一個isolate來處理,看上去相似js的Web Workerjson
先看下示意圖,總共須要4步來作:markdown
看代碼前先了解幾個關鍵類:app
對應的測試代碼:async
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; } 複製代碼
上面代碼對應的日誌以下:post
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] 複製代碼
若有問題歡迎指正~~測試