flutter isolate


你是怎么把工作放到后台線程的?

由於 Flutter 是單線程並且跑着一個 event loop 的(就像 Node.js 那樣),你不必為線程管理或是開啟后台線程而操心。如果你正在做 I/O 操作,如訪問磁盤或網絡請求,安全地使用 async / await 就完事了。如果,在另外的情況下,你需要做讓 CPU 執行繁忙的計算密集型任務,你需要使用 Isolate 來避免阻塞 event loop。

對於 I/O 操作,通過關鍵字 async,把方法聲明為異步方法,然后通過await關鍵字等待該異步方法執行完成(譯者語:這和javascript中是相同的):

這就是對諸如網絡請求或數據庫訪問等 I/O 操作的典型做法。

然而,有時候你需要處理大量的數據,這會導致你的 UI 掛起。在 Flutter 中,使用 Isolate 來發揮多核心 CPU 的優勢來處理那些長期運行或是計算密集型的任務。

Isolates 是分離的運行線程,並且不和主線程的內存堆共享內存。這意味着你不能訪問主線程中的變量,或者使用 setState()來更新 UI。正如它們的名字一樣,Isolates 不能共享內存。

下面的例子展示了一個簡單的 isolate,是如何把數據返回給主線程來更新 UI 的

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:isolate';

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  List widgets = [];

  @override
  void initState() {
    super.initState();
    loadData();
  }

  showLoadingDialog() {
    if (widgets.length == 0) {
      return true;
    }

    return false;
  }

  getBody() {
    if (showLoadingDialog()) {
      return getProgressDialog();
    } else {
      return getListView();
    }
  }

  getProgressDialog() {
    return Center(child: CircularProgressIndicator());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Sample App"),
        ),
        body: getBody());
  }

  ListView getListView() => ListView.builder(
      itemCount: widgets.length,
      itemBuilder: (BuildContext context, int position) {
        return getRow(position);
      });

  Widget getRow(int i) {
    return Padding(padding: EdgeInsets.all(10.0), child: Text("Row ${widgets[i]["title"]}"));
  }

  loadData() async {
    ReceivePort receivePort = ReceivePort();
    await Isolate.spawn(dataLoader, receivePort.sendPort);

    // The 'echo' isolate sends its SendPort as the first message
    SendPort sendPort = await receivePort.first;

    List msg = await sendReceive(sendPort, "https://jsonplaceholder.typicode.com/posts");

    setState(() {
      widgets = msg;
    });
  }

// the entry point for the isolate
  static dataLoader(SendPort sendPort) async {
    // Open the ReceivePort for incoming messages.
    ReceivePort port = ReceivePort();

    // Notify any other isolates what port this isolate listens to.
    sendPort.send(port.sendPort);

    await for (var msg in port) {
      String data = msg[0];
      SendPort replyTo = msg[1];

      String dataURL = data;
      http.Response response = await http.get(dataURL);
      // Lots of JSON to parse
      replyTo.send(json.decode(response.body));
    }
  }

  Future sendReceive(SendPort port, msg) {
    ReceivePort response = ReceivePort();
    port.send([msg, response.sendPort]);
    return response.first;
  }
}

遇到問題看上一篇:

這里還是補充一下

 首先在pubspec.yaml中添加https://www.cnblogs.com/wf-l5201314/p/10315922.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM