Olá! Boas-vindas ao curso de Background Tasks com Flutter.
Audiodescrição: William Bezerra é um homem pardo, com cabelo e barba preta. Usa óculos de grau de armação redonda e camiseta azul-escura. Ao fundo, uma parede lisa com ilumação degradê do rosa ao azul.
Te guiaremos nessa jornada, na qual aprenderemos sobre Background Tasks, que são atividades executadas em segundo plano, algo que já deve ser familiar para muitos. Por exemplo, no aplicativo WhatsApp, quando está sincronizando alguma coisa, ou no aplicativo do YouTube, quando está baixando um vídeo para assistir offline. Essas são as Background Tasks, e é isso que vamos aprender.
Ao longo desta jornada, utilizaremos o projeto de Checklist, que já construímos no curso de Codebase. Inclusive, fica aqui o convite para que o façam antes de iniciar este curso. No entanto, caso não tenham feito, não há problema. Vamos utilizar a base desse projeto, que já funciona offline e online.
O projeto já possui o conceito de Offline First aplicado, e vamos adicionar algumas funcionalidades para melhorar esse processo. Por exemplo, o aplicativo Offline First faz a sincronização de dados online e offline, mas muitas vezes só funciona quando o aplicativo está aberto. Mas, e se o aplicativo estiver fechado? Ao longo deste curso, faremos exatamente isso: criar atividades em background, ou seja, em segundo plano, para realizar essa sincronização de dados. No caso, apontando para o Codebase, mas você podera adaptar para o seu contexto.
Além disso, trabalharemos com notificações locais, disparando notificações via gatilhos e também agendando notificações. No projeto, haverá a opção de o usuário agendar uma notificação para o futuro, como um lembrete para checar o leite. Ele clicará no ícone de notificação e agendará para o futuro, como se fosse um alarme, para a notificação chegar. Nesse caso, a notificação chegará em 5 segundos, como demonstrado no emulador.
Por último, utilizaremos a geolocalização tanto no contexto de background task quanto no contexto do aplicativo, para criar alertas e gatilhos no contexto em que estamos aplicando.
Como mencionado, é muito importante que já tenham algum conhecimento sobre Offline First. Isso significa ter trabalhado em algum momento com um banco de dados local, com o próprio Codebase, seguindo o que foi ensinado no curso anterior, para ter uma base sólida e extrair o máximo de conteúdo deste curso. Trabalharemos tanto a questão da sincronização quanto as outras questões de notificações e localização mencionadas.
Além disso, é importante ter conhecimento de Flutter, uma base funcional de requisição de dados e compreensão da estrutura de dados, para garantir que extrairão todo o conteúdo. Gostou desse conteúdo? Esperamos você no próximo vídeo!
Imagine a seguinte situação, fomos contratados por uma grande rede varejista para dar continuidade a um aplicativo que já é utilizado por seus colaboradores. Este aplicativo é o mesmo que utilizamos para construir no curso de Codebase.
Inclusive, deixamos o convite para participar do curso de Codebase, que está muito interessante.
Em resumo, esse aplicativo é utilizado pelas pessoas colaboradoras para realizar checagens internas de produtos. Por exemplo, há produtos como arroz, feijão e xampu, e os colaboradores adicionam esses itens para que outros colaboradores possam checá-los e marcá-los como encontrados.
O aplicativo funciona tanto online quanto offline, ou seja, tem a premissa de ser offline first (prioritariamente offline). Isso ocorre porque, em supermercados, a conexão é geralmente instável. Certamente já passamos por situações em que estamos tentando enviar uma mensagem e a rede simplesmente cai. Essa é uma premissa deste aplicativo.
Entretanto, ao utilizar o aplicativo para adicionar itens e realizar checagens, surgiram alguns problemas. Quando os colaboradores voltavam para um ambiente online, após realizar as checagens, o aplicativo nem sempre sincronizava. Isso causou uma série de problemas, pois, às vezes, dois funcionários verificavam o mesmo item, já que ele não estava marcado no aplicativo.
Ao investigar, encontramos algumas inconsistências. Basicamente, o aplicativo sincroniza apenas se ainda estiver aberto. Ou seja, se encerrarmos o aplicativo, ele continua aberto em teoria, mas, quando a conexão é restabelecida, ele não sincroniza os dados. Isso ocorre porque ele não tem acesso a atividades em background (segundo plano), apenas em tempo real. Para os funcionários sincronizarem, eles precisariam abrir o aplicativo novamente sempre que estivessem conectados à internet. Isso é um problema, pois nem sempre eles se lembram de fazer isso.
Esse problema chega até nós, e precisamos resolvê-lo para garantir que o aplicativo, mesmo fechado, consiga sincronizar. Utilizaremos as background tasks, que são atividades executadas em segundo plano. Isso é comum em alarmes, WhatsApp, YouTube, entre outros contextos. Para aplicar esse cenário, utilizaremos um package do Flutter chamado WorkManager
, que possibilita a execução de tarefas em segundo plano tanto no Android quanto no iOS.
Após baixar o projeto, disponível na atividade anterior, você irá abrí-lo no VS Code. Feito isso, para adicionar o package ao projeto, abrimos o terminal e executamos comando flutter pub add workmanager
.
flutter pub add workmanager
Após executar, aguardamos a adição do package. Caso seu VS Code não execute ou não tenha essa configuração, você pode executar o comando flutter pub get
manualmente. Isso garantirá que todas as dependências sejam baixadas e que o aplicativo esteja sincronizado com elas.
Com o package no projeto, precisamos fazer as configurações nativas para que funcione. A background task ocorre dentro do sistema do dispositivo. No Android, não é necessário fazer nenhuma configuração adicional, pois todos os aplicativos já suportam esse processo de sincronização em segundo plano.
No entanto, no iOS, é necessário habilitar esse comando. Para isso, acessamos a pasta "iOS > Runner" e abrimos o arquivo info.plist
. Nele, temos uma série de dependências geradas por padrão na criação do aplicativo em Flutter.
Dentro das dependências dict
e plist
, adicionamos o comando abaixo:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>processing</string>
</array>
Esse comando adiciona uma nova chave chamada UIBackgroundModes
e habilita tanto o fetch (busca) quanto o processing (processamento). Isso permite que, quando o aplicativo rodar em segundo plano, ele consiga tanto buscar dados quanto processá-los.
Com o ambiente configurado, estamos prontos para executar nossa primeira tarefa em segundo plano.
Certo, mesmo que tenhamos configurado todo o pacote, adicionando as permissões de background, ainda assim não temos certeza de que essa atividade está funcional. Precisamos criar, pelo menos, uma task para assegurar e garantir que essa implementação foi feita corretamente. Para isso, vamos iniciar a configuração abrindo o arquivo main.dart
do nosso projeto.
callbackDispatcher()
Esse arquivo está fazendo a inicialização dos widgets, inicializando o codebase e rodando o aplicativo que foi construído. Dentro desse projeto, vamos criar uma implementação de background. Isso porque o background precisa rodar independente do aplicativo. No cenário geral, estará acima da execução do app, ou seja, não precisa que o app esteja rodando para ser executado.
Vamos criar uma função chamada void callbackDispatcher
, que será executada em background. Para isso, precisamos seguir o seguinte modelo.
@pragma(
'vm:entry-point'))
void callbackDispatcher(){}
A função callbackDispatcher()
terá uma annotation @pragma('vm:entry-point')
, que define que será um ponto de entrada para máquinas virtuais. Isso significa que essa função será acessível para máquinas virtuais, mesmo que não estejamos executando necessariamente o Flutter. Se trabalharmos com isolate ou background tasks específicas, também utilizaremos isolate, e precisamos definir isso na função para que ela seja acessada quando estiver executando fora do Flutter.
Dentro dessa função, chamaremos o Workmanager()
e, dentro dele, o método .executeTask()
, que utilizaremos para executar a task, então nos parênteses, passamos taskName,inputData
. Esse método sempre terá um retorno booleano, true
ou false
, que sinaliza para o Workmanager
se a execução foi bem-sucedida ou não. Ele possui parâmetros como taskName
e inputData
, mas isso fica dentro de uma estrutura mais definida.
Podemos executar, por exemplo, uma task em background. Então, passamos print('Minha primeira task em background')
. Na linha abaixo, passamos return true
.
@pragma('vm:entry-point')
void callbackDispatcher() {
Workmanager().executeTask(
(taskName, inputData) async {
print('Minha primeira task em background');
return true;
},
);
}
Feito isso, executamos e tudo da certo. Essa pode ser uma task em background. Com o callbackDispatcher
bem definido, executando a task, vamos fazer uma implementação no main
para inicializar esse método. Isso pode ser feito antes ou depois de iniciar o CodeBase Lite
, dependendo do uso. Nesse caso, será depois.
Chamaremos Workmanager()
e faremos um .initialize()
, chamando o método callbackDispatcher
para executar nosso método. O initialize
recebe um parâmetro chamado isInDebugMode
. Se deixarmos como true
, sempre que uma task em background for executada, um alerta será disparado no aplicativo, indicando sucesso ou falha. Então, podemos colocar isInDebugMode
como true
e executar para verificar se funcionou.
Workmanager().initialize(
callbackDispatcher,
isInDebugMode: true,
);
Deu certo. Com o método criado, vamos executar essa atividade. Até o momento, inicializamos o Workmanager
com o callbackDispatcher
para executar as atividades e criamos a execução. Porém, não programamos quando ela será disparada. Para isso, precisamos de uma configuração. Assim como ao agendar um alarme, precisamos agendar a task para o aplicativo entender que deve executá-la no momento certo.
Vamos abrir o aplicativo, acessar as pages e abrir a checklist_page.dart
, onde implementamos a lógica da aplicação. Dentro do Scaffold()
, próximo à linha 108, criaremos um método floatingActionButton: FloatingActionButton()
, que é o botão flutuante da aplicação. Passaremos um child: Icon()
antes de implementar a função, para não ficar sem função. Nos parênteses, passamos Icons.add
.
Após, na função onPressed
, utilizaremos para agendar nossa atividade. Então, na linha abaixo, chamamos o Workmanager()
e a função .registerPeriodicTask()
. Podemos usar oneTask
para executar uma vez ou periodic
para executar periodicamente. Neste caso, usaremos PeriodicTask
para executar várias vezes em intervalos definidos. Precisamos definir o nome e o ID, identificadores para usar no dispatcher
. Chamaremos o ID de first-task-id
e o nome de first-task
.
`checklist_page.dart
//código omitido
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Workmanager().registerPeriodicTask(
'first-task-id',
'first-task',
);
},
),
Assim, registramos a atividade para execução. Porém, existem parâmetros adicionais, como a frequency
que recebe um Duration()
. Podemos definir dias, horas, minutos, segundos, milissegundos, microsegundos. Por exemplo, podemos executar a cada 30 dias ou a cada 1 hora. O limite é 15 minutos, pois no Android não é possível menos que isso. Nesse caso, definiremos a frequência como minutes: 15
.
//código omitido
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Workmanager().registerPeriodicTask(
'first-task-id',
'first-task',
frequency: const Duration(minutes: 15),
);
},
),
Com a aplicação registrando a atividade, encerramos a execução atual e a reiniciamos. Por padrão, o aplicativo inicializa e executa a task automaticamente, registrando-a em background para garantir o funcionamento. Nos consoles, vemos a inicialização do aplicativo, instalação das dependências e execução da primeira task em background. Se abrimos o aplicativo, temos a notificação que mostra que a tarefa foi executada com sucesso.
Entretanto, a atividade não está registrada para execução frequente. Precisamos registrar essa atividade, para isso, executamos o método implementado no onPressed
do FloatingActionButton
, registrando a task firstTask
com frequência de 15 minutos. No simulador, ao clicar no botão de "+" a tarefa é registrada e executada. A notificação sonora confirma a execução e sucesso. No console, vemos a mensagem "Minha primeira task em background" e o log WorkResultSuccess
, indicando sucesso.
A partir disso, a cada 15 minutos, a task em background será executada, seguindo o padrão definido. Com a implementação funcional, podemos aguardar 15 minutos para verificar sucesso ou erro, mas toda a implementação está correta.
O curso Flutter: trabalhando com background tasks em um app possui 164 minutos de vídeos, em um total de 45 atividades. Gostou? Conheça nossos outros cursos de Flutter em Mobile, ou leia nossos artigos de Mobile.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.