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
- Funció de l'Isolate:
isolateFunction
és la funció que s'executarà en un isolate separat. Aquesta funció rep unSendPort
per enviar missatges de tornada al fil principal. - Creació del
ReceivePort
: ElReceivePort
s'utilitza per rebre missatges de l'isolate. - Creació de l'Isolate:
Isolate.spawn
crea un nou isolate i executaisolateFunction
, passant-li elSendPort
delReceivePort
. - 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
- Què és Flutter?
- Configuració de l'Entorn de Desenvolupament
- Comprensió de l'Arquitectura de Flutter
- Creació de la Teva Primera Aplicació Flutter
Mòdul 2: Conceptes Bàsics de Programació en Dart
- Introducció a Dart
- Variables i Tipus de Dades
- Sentències de Flux de Control
- Funcions i Mètodes
- Programació Orientada a Objectes en Dart
Mòdul 3: Widgets de Flutter
- Introducció als Widgets
- Widgets Stateless vs Stateful
- Widgets Bàsics
- Widgets de Disseny
- Widgets d'Entrada i Formulari
Mòdul 4: Gestió de l'Estat
Mòdul 5: Navegació i Enrutament
- Introducció a la Navegació
- Navegació Bàsica
- Rutes Nomenades
- Passar Dades Entre Pantalles
- Deep Linking
Mòdul 6: Xarxes i APIs
- Obtenir Dades d'Internet
- Analitzar Dades JSON
- Gestió d'Errors de Xarxa
- Ús d'APIs REST
- Integració de GraphQL
Mòdul 7: Persistència i Emmagatzematge
- Introducció a la Persistència
- Preferències Compartides
- Emmagatzematge de Fitxers
- Base de Dades SQLite
- Ús de Hive per a l'Emmagatzematge Local
Mòdul 8: Conceptes Avançats de Flutter
- Animacions en Flutter
- Pintura Personalitzada i Canvas
- Canals de Plataforma
- Isolates i Concurrència
- Optimització del Rendiment
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries
- Proves de Widgets
- Proves d'Integració
- Tècniques de Depuració
Mòdul 10: Desplegament i Manteniment
- Preparació per al Llançament
- Construcció per a iOS
- Construcció per a Android
- Integració i Desplegament Continu (CI/CD)
- Manteniment i Actualització de la Teva Aplicació