Flutter - Apresentando Stream
Hoje veremos o conceito de Stream no Flutter. |
|
O que é o Flutter ?
O Flutter é um SDK de aplicativo móvel do Google que ajuda a criar aplicativos móveis modernos para iOS e Android usando uma única (quase) base de código.
Se você não conhece o Flutter veja o meu artigo : Flutter - Primeiros contatos e impressões
Apresentando o conceito de Stream
O conceito de stream esta relacionado com a programação assíncrona. (A tradução literal para stream seria fluxo. Pense em um stream como um fluxo assincrono de dados.)
Vamos começar com a definição dada pela documentação do DART.
Veja também as vídeo aulas do minicurso de Flutter:
Quais os objetivos de um Stream ?
- Streams fornecem uma sequência
assíncrona de dados;
- Sequências de dados incluem eventos gerados pelo usuário e leitura de dados de
arquivos;
- Você pode processar um stream usando await for ou listen() a
partir da API Stream;
- Os streams fornecem uma maneira de responder a erros;
- Existem dois tipos de streams:
single subscription(assinatura
única) ou broadcast
(múltiplas assinaturas);
Dessa forma a programação assíncrona no Dart usa as classes: Future e Stream.
Se você entendeu o conceito, então parabéns, pois não é tão simples assim...
Resumindo: Um stream é uma sequência de eventos assíncronos. Diferentemente de Future um Stream notifica quando existe um evento pronto.
Assim:
Para poder criar um stream usamos a classe StreamController que funciona como um controlador do stream, e, que contém um stream que permite ao ouvinte ou consumidor enviar dados, eventos concluídos ou erros.
Para incluir dados no stream usamos o método add do objeto sink (sink.add) e para acessar o stream usamos o método listen do objeto stream.(stream.listen).
A classe EventSink<T> contém o método add para alimentar dados no stream, e isso dispara o evento do ouvinte de dados.
O método listen() no stream também pode capturar mensagens de erro. Isso ocorre porque um objeto StreamSubscription<T> é gerado sempre que você ouve(listen) um stream. Este objeto é o motivo de poder lidar com vários eventos, como dados, erros e concluído(quando o método close() for chamado no stream).
Vamos agora ver esse conceito na prática...
Usando stream na prática
O código a seguir pode ser criado em uma aplicação Flutter ou você pode usar o editor online para a linguagem Dart neste link: https://dartpad.dartlang.org/
Primeiro vamos criar um Stream para gerar números aleatórios definindo a classe NumeroAleatorio() com o código abaixo:
import 'dart:async';
import 'dart:math' as Math;
class NumeroAleatorio {
final StreamController _controller = StreamController<int>();
int _contador = Math.Random().nextInt(100);
int numeroVezes = 0;
NumeroAleatorio() {
Timer.periodic(Duration(seconds: 1), (timer){
_controller.sink.add(_contador);
_contador = Math.Random().nextInt(100);
numeroVezes += 1;
if (numeroVezes > 7) {
timer.cancel();
_controller.sink.close();
}
});
}
Stream<int> get stream => _controller.stream;
}
|
Criamos um stream:
final StreamController _controller = StreamController<int>();
Adicionamos dados ao stream usando o método add do objeto sink:
_controller.sink.add(_contador);
Fechamos o stream o método close do objeto sink após 7 números aleatórios:
_controller.sink.close();
Definimos a propriedade get stream que permite passar os dados do stream para os ouvintes:
Stream<int> get stream => _controller.stream;
Vamos agora definir no método main() o
código que vai consumir o stream criado.
void main() {
final randomNumStream = NumeroAleatorio().stream;
final subscription = randomNumStream.listen(
(data){
print('Data: $data');
},
onError: (err) {
print('Error: $err');
},
cancelOnError: false,
onDone: (){
print('Concluído');
}
);
}
|
Acessamos o stream criado na classe NumeroAleatorio():
final randomNumStream = NumeroAleatorio().stream;
Usamos o método listen() para adicionar um ouvinte ao stream e acessar os dados ou erros no stream:
final
subscription = randomNumStream.listen(
(data){
print('Numeros : $data');
},
onError: (err) {
print('Error: $err');
},
cancelOnError: false,
onDone: (){
print('Concluído');
}
);
Na função
main(), podemos usar outros métodos do objeto de
assinatura para pausar, retomar e fechar a escuta do fluxo.
Uma coisa que devemos lembrar é que um ouvinte pode ser usado apenas uma uma
vez. Isso significa que, se quisermos usar o ouvinte mais de uma vez para o
mesmo stream, ele não funcionará para o segundo ouvinte.
Executando o projeto teremos o resultado abaixo:
Em outro artigo vamos continuar a tratar de stream, StreamBuilder e conceitos relacionados.
"Porque o
Senhor é justo, e ama a justiça; o seu rosto olha para os retos."
Salmos 11:7
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
Flutter - Apresentando o widget MaterialApp - Macoratti
Flutter - Apresentando Flutter Studio - Macoratti
Flutter - Lista Básica - Macoratti
Flutter - Apresentando Widgets - Macoratti
Flutter - Obtendo dados da Web - Macoratti