Introducció

En aquest tema, explorarem els conceptes d'isolates i concurrència en Flutter. La concurrència és crucial per a desenvolupar aplicacions que siguin responsives i eficients, especialment quan es tracta de tasques intensives en càlcul o operacions d'entrada/sortida (I/O) que poden bloquejar el fil principal de l'aplicació.

Què són els Isolates?

Els isolates són unitats d'execució independents en Dart. Cada isolate té la seva pròpia memòria i no comparteix estat amb altres isolates. Això permet executar tasques en paral·lel sense preocupar-se per les condicions de carrera o altres problemes de sincronització.

Característiques dels Isolates

  • Memòria Independent: Cada isolate té la seva pròpia memòria, el que significa que no hi ha compartició directa d'estat entre isolates.
  • Comunicació per Missatges: Els isolates es comuniquen entre ells mitjançant l'enviament de missatges.
  • Execució Paral·lela: Els isolates poden executar-se en paral·lel, aprofitant els múltiples nuclis del processador.

Creació i Ús d'Isolates

Exemple Bàsic

A continuació, es mostra un exemple bàsic de com crear i utilitzar un isolate en Dart:

import 'dart:isolate';

// Funció que s'executarà en un isolate separat
void isolateFunction(SendPort sendPort) {
  int result = 0;
  for (int i = 0; i < 1000000000; i++) {
    result += i;
  }
  sendPort.send(result);
}

void main() async {
  // Crear un port de recepció per rebre missatges de l'isolate
  ReceivePort receivePort = ReceivePort();

  // Crear un isolate
  await Isolate.spawn(isolateFunction, receivePort.sendPort);

  // Esperar el resultat de l'isolate
  receivePort.listen((message) {
    print('Resultat de l\'isolate: $message');
    receivePort.close();
  });
}

Explicació del Codi

  1. Funció de l'Isolate: isolateFunction és la funció que s'executarà en un isolate separat. Aquesta funció rep un SendPort per enviar missatges de tornada al fil principal.
  2. Creació del ReceivePort: El ReceivePort s'utilitza per rebre missatges de l'isolate.
  3. Creació de l'Isolate: Isolate.spawn crea un nou isolate i executa isolateFunction, passant-li el SendPort del ReceivePort.
  4. Recepció del Missatge: El ReceivePort escolta els missatges enviats des de l'isolate i imprimeix el resultat.

Concurrència en Flutter

En Flutter, la concurrència es gestiona principalment mitjançant el paquet dart:async, que proporciona futures, streams i altres eines per treballar amb operacions asíncrones.

Futures

Un Future representa una operació que es completarà en algun moment en el futur. Els futures són ideals per a operacions d'I/O com ara llegir fitxers o fer sol·licituds de xarxa.

Exemple de Future

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Dades obtingudes';
}

void main() async {
  print('Inici de la sol·licitud');
  String data = await fetchData();
  print(data);
  print('Fi de la sol·licitud');
}

Streams

Un Stream és una seqüència d'esdeveniments asíncrons. Els streams són útils per a operacions que produeixen múltiples valors al llarg del temps, com ara la lectura de dades d'un sensor.

Exemple de Stream

Stream<int> countStream(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

void main() async {
  await for (int i in countStream(5)) {
    print(i);
  }
}

Exercicis Pràctics

Exercici 1: Càlcul en un Isolate

Crea un isolate que calculi la suma dels primers 1.000.000 nombres naturals i envia el resultat al fil principal.

Solució

import 'dart:isolate';

void sumIsolate(SendPort sendPort) {
  int sum = 0;
  for (int i = 1; i <= 1000000; i++) {
    sum += i;
  }
  sendPort.send(sum);
}

void main() async {
  ReceivePort receivePort = ReceivePort();
  await Isolate.spawn(sumIsolate, receivePort.sendPort);

  receivePort.listen((message) {
    print('Suma dels primers 1.000.000 nombres: $message');
    receivePort.close();
  });
}

Exercici 2: Flux de Dades amb Streams

Crea un stream que emeti els nombres parells de 0 a 20 amb un retard d'1 segon entre cada emissió.

Solució

Stream<int> evenNumberStream(int max) async* {
  for (int i = 0; i <= max; i += 2) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

void main() async {
  await for (int number in evenNumberStream(20)) {
    print(number);
  }
}

Resum

En aquest tema, hem après sobre els isolates i la concurrència en Flutter. Hem vist com els isolates permeten l'execució paral·lela de tasques sense compartir estat, i com utilitzar futures i streams per gestionar operacions asíncrones. Aquests conceptes són fonamentals per desenvolupar aplicacions Flutter eficients i responsives.

Curs de Desenvolupament Flutter

Mòdul 1: Introducció a Flutter

Mòdul 2: Conceptes Bàsics de Programació en Dart

Mòdul 3: Widgets de Flutter

Mòdul 4: Gestió de l'Estat

Mòdul 5: Navegació i Enrutament

Mòdul 6: Xarxes i APIs

Mòdul 7: Persistència i Emmagatzematge

Mòdul 8: Conceptes Avançats de Flutter

Mòdul 9: Proves i Depuració

Mòdul 10: Desplegament i Manteniment

Mòdul 11: Flutter per a Web i Escriptori

© Copyright 2024. Tots els drets reservats