Este artigo tem o intuito de demonstrar como você pode implementar Background Services em seus Apps feitos com Xamarin.Forms de uma forma simples, rápida e fácil.
O que é
Background Services ou Serviços em Segundo Plano, de uma maneira bem simplista, é quando de acordo com a lógica de negócio ou o propósito do App em questão, necessitamos realizar algumas tarefas sem que impossibilite o uso da aplicação pelo usuário.
ADICIONANDO O NUGET PACKAGE
Para o exemplo será utilizado o plugin Matcha.BackgroundService, instale o plugin em todos os seus projetos.
Inicializando o Plugin
É necessário a inicialização do plugin em cada uma das plataformas, para isso adicione BackgroundAggregator.Init(this) nas classes de inicialização.
Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Android.App; | |
using Android.Content.PM; | |
using Android.Runtime; | |
using Android.OS; | |
using Matcha.BackgroundService.Droid; | |
namespace DemoBackground.Droid | |
{ | |
[Activity(Label = "DemoBackground", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] | |
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity | |
{ | |
protected override void OnCreate(Bundle savedInstanceState) | |
{ | |
TabLayoutResource = Resource.Layout.Tabbar; | |
ToolbarResource = Resource.Layout.Toolbar; | |
base.OnCreate(savedInstanceState); | |
Xamarin.Essentials.Platform.Init(this, savedInstanceState); | |
global::Xamarin.Forms.Forms.Init(this, savedInstanceState); | |
BackgroundAggregator.Init(this); | |
LoadApplication(new App()); | |
} | |
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) | |
{ | |
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); | |
base.OnRequestPermissionsResult(requestCode, permissions, grantResults); | |
} | |
} | |
} |
iOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Foundation; | |
using Matcha.BackgroundService.iOS; | |
using UIKit; | |
namespace DemoBackground.iOS | |
{ | |
[Register("AppDelegate")] | |
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate | |
{ | |
public override bool FinishedLaunching(UIApplication app, NSDictionary options) | |
{ | |
global::Xamarin.Forms.Forms.Init(); | |
BackgroundAggregator.Init(this); | |
LoadApplication(new App()); | |
return base.FinishedLaunching(app, options); | |
} | |
} | |
} |
BackgroundService.cs
Crie a classe BackGroundService e implemente a interface IPeriodicTask.
No construtor, receba como parâmetro um inteiro, ele será o tempo para definir o intervalo de execução da sua tarefa (neste exemplo em segundos).
Atribua o parâmetro na variável Interval.
No método StartJob é onde a “mágica irá acontecer de fato”. Ou seja, aqui você irá definir o que deseja realizar em background. Para este exemplo eu estou apenas imprimindo no console a data atual.
Dependendo da sua lógica, as vezes é interessante que depois de uma determinada ação esse serviço em background não aconteça novamente, para isso apenas retorne False no método StartJob.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading.Tasks; | |
using Matcha.BackgroundService; | |
namespace DemoBackground.Services | |
{ | |
public class BackgroundService : IPeriodicTask | |
{ | |
public TimeSpan Interval { get; set; } | |
public BackgroundService(int seconds) | |
{ | |
Interval = TimeSpan.FromSeconds(seconds); | |
} | |
public async Task<bool> StartJob() | |
{ | |
Console.WriteLine(DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss")); | |
//Return true para continuar | |
return true; | |
//Return false para parar | |
//return false; | |
} | |
} | |
} |
App.cs
Sobrescreva o método OnStart e registre o seu serviço utilizando BackgroundAggregatorService.Add e passe como parâmetro o tempo de intervalo desejado. Neste exemplo defini 15 segundos. Em seguida inicie o seu serviço em background utilizando StartBackgroundService como demonstrado a seguir.
Sobrescreva o método OnSleep para que o seu serviço em background pause quando sua aplicação não estiver sendo utilizada.
Sobrescreva o método OnResume para que o seu serviço comece novamente quando a sua aplicação voltar a ser utilizada.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using DemoBackground.Services; | |
using Matcha.BackgroundService; | |
using Xamarin.Forms; | |
namespace DemoBackground | |
{ | |
public partial class App : Application | |
{ | |
public App() | |
{ | |
InitializeComponent(); | |
MainPage = new Views.MainPage(); | |
} | |
protected override void OnStart() | |
{ | |
// Registra | |
BackgroundAggregatorService.Add(() => new BackgroundService(15)); | |
// Inicia | |
BackgroundAggregatorService.StartBackgroundService(); | |
} | |
protected override void OnSleep() | |
{ | |
// Para | |
BackgroundAggregatorService.StopBackgroundService(); | |
} | |
protected override void OnResume() | |
{ | |
// Inicia Novamente | |
BackgroundAggregatorService.StartBackgroundService(); | |
} | |
} | |
} |
Resultado
Esse e todos os exemplos deste blog encontram-se disponíveis no GitHub.