Sobes.tech
Middle

Cum să creezi două fire în Dart în contextul Flutter?

sobes.tech AI

Răspuns de la AI

Pentru a crea fire de execuție independente în Dart/Flutter, se utilizează Izolate (Isolates). Acestea reprezintă sarcini separate cu propriul spațiu de memorie dedicat, ceea ce previne problemele de acces concurent la date și blocarea firului principal (firul UI).

Există mai multe moduri de a crea și de a interacționa cu izolatele:

  1. Isolate.spawn(): Mod de nivel inferior pentru crearea unui izolator. Necesită transmiterea unei funcții de nivel superior sau a unei metode statice de clasă pentru a fi executată în noul izolator și a unui port pentru schimbul de mesaje.

    import 'dart:isolate';
    
    // Funcție care rulează în izolator
    void isolateEntry(SendPort sendPort) {
      int result = 0;
      for (int i = 0; i < 1000000000; i++) {
        result += i;
      }
      sendPort.send(result);
    }
    
    void main() async {
      ReceivePort receivePort = ReceivePort();
      Isolate isolate = await Isolate.spawn(isolateEntry, receivePort.sendPort);
      receivePort.listen((message) {
        print('Rezultatul izolatorului: $message');
        isolate.kill();
      });
      print('Firul principal continuă să funcționeze...');
    }
    
  2. compute(): O funcție simplificată din pachetul flutter/foundation, care utilizează Isolate.spawn() în fundal. Este ideală pentru sarcini simple de fundal care nu necesită interacțiuni complexe cu izolatorul.

    import 'package:flutter/foundation.dart';
    
    int heavyComputation(int limit) {
      int result = 0;
      for (int i = 0; i < limit; i++) {
        result += i;
      }
      return result;
    }
    
    void main() async {
      int result = await compute(heavyComputation, 1000000000);
      print('Rezultatul calculelor: $result');
    }
    
  3. Isolate.spawnUri(): Se folosește pentru a porni cod dintr-un fișier Dart separat într-un izolator nou.

Interacțiunea între izolatoare:

Izolatele schimbă date doar prin trimiterea de mesaje prin instanțe de SendPort și ReceivePort. Aceste operații sunt atomice.

  • SendPort: Se folosește pentru a trimite mesaje dintr-un izolator în altul.
  • ReceivePort: Se folosește pentru a asculta mesajele primite.

Atunci când se transferă obiecte între izolatoare, acestea trebuie să fie "transferabile", ceea ce include:

  • Tipuri de date simple (int, double, String, bool)
  • Liste și hărți care conțin tipuri transferabile
  • Anumite tipuri specifice Flutter care pot fi serializate

Obiectele care nu sunt transferabile vor fi copiate, iar modificările ulterioare într-un izolator nu vor fi reflectate în celălalt.

Puncte cheie:

  • Izolatele nu pot accesa direct memoria celuilalt.
  • Nu au acces la starea comună, inclusiv variabile, clase și widget-uri ale izolatorului principal (firul UI).
  • Comunicația între izolatoare are loc asincron.
  • La lucrul cu izolatoare în Flutter, este important să gestionezi corect ciclul de viață (de exemplu, să folosești isolate.kill() dacă este necesar).

Utilizarea izolatoarelor permite efectuarea de operații lungi sau intensive în resurse în fundal, evitând blocarea interfeței utilizatorului și asigurând o funcționare lină a aplicației.