flutter實現異步UI

      網友投稿 861 2022-05-29

      1.runOnUiThread 在Flutter中等價于什么

      Dart是單線程執行模型,支持Isolates(在另一個線程上運行Dart代碼的方式)、事件循環和異步編程。 除非您啟動一個Isolate,否則您的Dart代碼將在主UI線程中運行,并由事件循環驅動。可以在UI線程上運行網絡請求代碼而不會導致UI掛起,因為網絡請求是異步的:

      loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; try{ Response response = await Dio().get(dataURL,options: Options(responseType: ResponseType.json),); setState(() {// 更新UI json = response.data; }); }catch(e){ print(e); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      要更新UI,可以調用setState,這會觸發build方法再次運行并更新數據。

      2.AsyncTask和IntentService在Flutter中等價于什么

      在Android中,當你想訪問一個網絡資源時,你通常會創建一個AsyncTask,它將在UI線程之外運行代碼來防止你的UI被阻塞。 AsyncTask有一個線程池,可以為你管理線程。

      由于Flutter是單線程的,運行一個事件循環(如Node.js),所以您不必擔心線程管理或者使用AsyncTasks、IntentServices。

      要異步運行代碼,可以將函數聲明為異步函數,并在該函數中等待這個耗時任務:

      loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; try{ Response response = await Dio().get(dataURL,options: Options(responseType: ResponseType.json),); setState(() {// 更新UI json = response.data; }); }catch(e){ print(e); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      這就是典型的進行網絡或數據庫調用的方式

      在Android上,當您繼承AsyncTask時,通常會覆蓋3個方法,OnPreExecute、doInBackground和onPostExecute。 在Flutter中沒有這種模式的等價物,只需等待一個長時間運行的函數,而Dart的事件循環將負責其余的事情。

      但是,有時可能需要處理大量數據,導致UI可能會掛起。在Flutter中,可以利用多個CPU內核來執行耗時或計算密集型任務。 這是通過使用Isolates來完成的。

      是一個獨立的執行線程,它運行時不會與主線程共享任何內存。這意味著你不能從該線程訪問變量或通過調用setState來更新你的UI。

      Isolate的例子,以及如何與主線程通信和共享數據以更新UI:

      List messages; loadData() async { // 當前線程的信息的接收者 ReceivePort receivePort = new ReceivePort(); /** * 創建并生成與當前隔離共享相同代碼的隔離。 * Isolate.spawn 接受的方法必須是靜態的或是一個頂層函數 * 傳遞當前接收者receivePort.sendPort給其他線程,那么其他線程就可以通過它,與當前線程通信 * */ await Isolate.spawn(dataLoader, receivePort.sendPort); SendPort sendPort = await receivePort.first; String dataURL = "https://jsonplaceholder.typicode.com/posts"; /// 向其他線程發送消息 var msg = await sendReceive(sendPort,dataURL); setState(() { /// 更新UI,setState會觸發build的執行 messages = msg; print(messages); }); } static dataLoader(SendPort sendPort) async{ /// 其他線程的消息接收者 ReceivePort receivePort = new ReceivePort(); /// 通知其他isolate,當前isolate監聽的端口 sendPort.send(receivePort.sendPort); await for(var msg in receivePort){ String data = msg[0]; // 獲取URL SendPort replyTo = msg[1]; // 回傳消息用的 String dataURL = data; /// 進行網絡請求 Response response = await Dio().get(dataURL,options: Options(responseType: ResponseType.json),); /// 將結果回傳回去 replyTo.send(response.data); } } /// 向其他線程發送消息 Future sendReceive(SendPort port,msg){ /// 當前線程的接收者 ReceivePort receivePort = new ReceivePort(); /// 向其他線程發送消息 port.send([msg,receivePort.sendPort]); return receivePort.first; }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      “dataLoader”是在它自己的獨立執行線程中運行的隔離區,可以在其中執行CPU密集型任務,例如解析大于1萬的JSON或執行計算密集型數學計算。

      完整示例:

      import 'dart:convert'; import 'dart:isolate'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; void main() => runApp(DemoApp()); class DemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: '導航演示1', home: new MyAppHome(), ); } } class MyAppHome extends StatefulWidget { @override MyAppHomeState createState() => MyAppHomeState(); } class MyAppHomeState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Hello"), ), body: Center( child: RaisedButton( child: Text("Go"), onPressed: () { loadData(); }, ), ), ); } List messages; loadData() async { // 當前線程的信息的接收者 ReceivePort receivePort = new ReceivePort(); /** * 創建并生成與當前隔離共享相同代碼的隔離。 * Isolate.spawn 接受的方法必須是靜態的或是一個頂層函數 * 傳遞當前接收者receivePort.sendPort給其他線程,那么其他線程就可以通過它,與當前線程通信 * */ await Isolate.spawn(dataLoader, receivePort.sendPort); SendPort sendPort = await receivePort.first; String dataURL = "https://jsonplaceholder.typicode.com/posts"; /// 向其他線程發送消息 List msg = await sendReceive(sendPort,dataURL); setState(() { /// 更新UI,setState會觸發build的執行 messages = msg; print(messages[0]["title"]); }); } static dataLoader(SendPort sendPort) async{ /// 其他線程的消息接收者 ReceivePort receivePort = new ReceivePort(); /// 通知其他isolate,當前isolate監聽的端口 sendPort.send(receivePort.sendPort); await for(var msg in receivePort){ String data = msg[0]; // 獲取URL SendPort replyTo = msg[1]; // 回傳消息用的 String dataURL = data; /// 進行網絡請求 Response response = await Dio().get(dataURL); /// 將結果回傳回去 replyTo.send(jsonDecode(response.toString())); } } /// 向其他線程發送消息 Future sendReceive(SendPort port,msg){ /// 當前線程的接收者 ReceivePort receivePort = new ReceivePort(); /// 向其他線程發送消息 port.send([msg,receivePort.sendPort]); return receivePort.first; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      flutter實現異步UI

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      Flutter iOS 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:JVM內存結構分析
      下一篇:【重構前端知識體系之HTML】2022,你還會來看HTML嗎?帶你重溫亦或走進!
      相關文章
      中文字幕亚洲综合久久综合| 亚洲中文字幕人成乱码| 亚洲一区二区三区在线网站| 一区二区三区亚洲| 久久久久亚洲AV无码专区首| 亚洲AV永久无码区成人网站| 亚洲AV无码欧洲AV无码网站| 久久久久亚洲av无码尤物| 国产亚洲综合色就色| 亚洲不卡中文字幕无码| 亚洲精品高清国产一线久久| 亚洲AV无码乱码在线观看裸奔| 久久久久亚洲精品成人网小说| 亚洲最大福利视频网站| 337p日本欧洲亚洲大胆色噜噜| 99久久亚洲综合精品成人网| 亚洲福利一区二区| 亚洲人成免费电影| 国产亚洲中文日本不卡二区| 亚洲乱亚洲乱妇24p| 亚洲AV人无码激艳猛片| 国产成人精品亚洲日本在线| 亚洲不卡影院午夜在线观看| 亚洲精品日韩一区二区小说| 久久人午夜亚洲精品无码区| 另类小说亚洲色图| 国产亚洲美日韩AV中文字幕无码成人| 亚洲最大av无码网址| 区久久AAA片69亚洲| 情人伊人久久综合亚洲| 亚洲男人天堂av| 亚洲av无码一区二区三区观看| 在线精品亚洲一区二区 | 亚洲av无码片在线观看| 亚洲欧洲另类春色校园小说| 亚洲国产成人精品无码区在线网站| 亚洲第一成人在线| 色综合久久精品亚洲国产| 亚洲色婷婷综合开心网| 亚洲成亚洲乱码一二三四区软件| 亚洲一区二区在线免费观看|