Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este guia discute como agendar o trabalho em segundo plano usando a API do Agendador de Trabalho android, que está disponível em dispositivos Android que executam o Android 5.0 (nível de API 21) e superior.
Visão geral
Uma das melhores maneiras de manter um aplicativo Android responsivo ao usuário é garantir que o trabalho complexo ou de execução longa seja executado em segundo plano. No entanto, é importante que o trabalho em segundo plano não afete negativamente a experiência do usuário com o dispositivo.
Por exemplo, um trabalho em segundo plano pode sondar um site a cada três ou quatro minutos para consultar alterações em um conjunto de dados específico. Isso parece benigno, no entanto, teria um impacto desastroso na duração da bateria. O aplicativo ativará repetidamente o dispositivo, elevará a CPU para um estado de energia mais alto, ligará os rádios, fará as solicitações de rede e, em seguida, processará os resultados. Ele fica pior porque o dispositivo não desligará imediatamente e retornará ao estado ocioso de baixa potência. O trabalho em segundo plano mal agendado pode inadvertidamente manter o dispositivo em um estado com requisitos de energia desnecessários e excessivos. Essa atividade aparentemente inocente (sondar um site) tornará o dispositivo inutilizável em um período relativamente curto de tempo.
O Android fornece as SEGUINTEs APIs para ajudar na execução do trabalho em segundo plano, mas por si só elas não são suficientes para agendamento de trabalho inteligente.
- Serviços de Intenção – os Serviços de Intenção são ótimos para executar o trabalho, no entanto, eles não fornecem nenhuma maneira de agendar o trabalho.
- AlarmManager – essas APIs só permitem que o trabalho seja agendado, mas não fornecem nenhuma maneira de realmente executar o trabalho. Além disso, o AlarmManager só permite restrições baseadas em tempo, o que significa gerar um alarme em um determinado momento ou após um determinado período de tempo ter decorrido.
- Receptores de Difusão – um aplicativo Android pode configurar receptores de transmissão para executar o trabalho em resposta a eventos ou Intenções em todo o sistema. No entanto, os receptores de transmissão não fornecem nenhum controle sobre quando o trabalho deve ser executado. Também as alterações no sistema operacional Android restringirão quando os receptores de transmissão funcionarem ou os tipos de trabalho aos quais eles podem responder.
Há dois recursos importantes para executar com eficiência o trabalho em segundo plano (às vezes chamado de trabalho em segundo plano ou trabalho):
- Agendamento inteligente do trabalho – é importante que, quando um aplicativo está fazendo um trabalho em segundo plano, ele o faça como um bom cidadão. O ideal é que o aplicativo não exija que um trabalho seja executado. Em vez disso, o aplicativo deve especificar condições que devem ser atendidas para quando o trabalho pode ser executado e, em seguida, agendar esse trabalho com o sistema operacional que executará o trabalho quando as condições forem atendidas. Isso permite que o Android execute o trabalho para garantir a máxima eficiência no dispositivo. Por exemplo, as solicitações de rede podem ser executadas em lote para serem executadas ao mesmo tempo para fazer uso máximo da sobrecarga envolvida com a rede.
- Encapsulando o trabalho – o código para executar o trabalho em segundo plano deve ser encapsulado em um componente discreto que pode ser executado independentemente da interface do usuário e será relativamente fácil de reagendar se o trabalho não for concluído por algum motivo.
O Agendador de Trabalhos do Android é uma estrutura interna do sistema operacional Android que fornece uma API fluente para simplificar o agendamento de trabalho em segundo plano. O Agendador de Trabalhos do Android consiste nos seguintes tipos:
- O
Android.App.Job.JobScheduleré um serviço do sistema usado para agendar, executar e, se necessário, cancelar trabalhos em nome de um aplicativo Android. - Uma
Android.App.Job.JobServiceé uma classe abstrata que deve ser estendida com a lógica que executará o trabalho no thread main do aplicativo. Isso significa que oJobServiceé responsável por como o trabalho deve ser executado de forma assíncrona. - Um
Android.App.Job.JobInfoobjeto contém os critérios para orientar o Android quando o trabalho deve ser executado.
Para agendar o trabalho com o Agendador de Trabalho do Android, um aplicativo Xamarin.Android deve encapsular o código em uma classe que estende a JobService classe. JobService tem três métodos de ciclo de vida que podem ser chamados durante o tempo de vida do trabalho:
bool OnStartJob(parâmetros JobParameters) – esse método é chamado pelo para executar o
JobSchedulertrabalho e é executado no thread main do aplicativo. É responsabilidade doJobServiceexecutar o trabalho de forma assíncrona e retornartruese houver trabalho restante oufalsese o trabalho for feito.Quando o
JobSchedulerchamar esse método, ele solicitará e reterá um wakelock do Android durante o trabalho. Quando o trabalho for concluído, é responsabilidade doJobServiceinformar oJobSchedulerfato por meio da chamada do método (descrito aJobFinishedseguir).JobFinished(Parâmetros JobParameters, bool needsReschedule) – Esse método deve ser chamado pelo
JobServicepara informarJobSchedulerque o trabalho foi feito. SeJobFinishednão for chamado, oJobSchedulernão removerá o wakelock, causando esvaziamento desnecessário da bateria.bool OnStopJob(parâmetros JobParameters) – isso é chamado quando o trabalho é interrompido prematuramente pelo Android. Ele deverá retornar
truese o trabalho deve ser reagendado com base nos critérios de repetição (discutidos abaixo com mais detalhes).
É possível especificar restrições ou gatilhos que controlarão quando um trabalho pode ou deve ser executado. Por exemplo, é possível restringir um trabalho para que ele só seja executado quando o dispositivo estiver carregando ou para iniciar um trabalho quando uma imagem for tirada.
Este guia discutirá detalhadamente como implementar uma JobService classe e agendá-la com o JobScheduler.
Requisitos
O Agendador de Trabalhos do Android requer o nível 21 da API do Android (Android 5.0) ou superior.
Usando o Agendador de Trabalhos do Android
Há três etapas para usar a API JobScheduler do Android:
- Implemente um tipo JobService para encapsular o trabalho.
- Use um
JobInfo.Builderobjeto para criar oJobInfoobjeto que manterá os critérios para oJobSchedulerexecutar o trabalho. - Agende o trabalho usando
JobScheduler.Schedule.
Implementar um JobService
Todo o trabalho executado pela biblioteca do Agendador de Trabalhos do Android deve ser feito em um tipo que estenda a Android.App.Job.JobService classe abstrata. A criação de um JobService é muito semelhante à criação de um Service com a estrutura do Android:
- Estenda a
JobServiceclasse . - Decore a subclasse com o
ServiceAttributee defina oNameparâmetro como uma cadeia de caracteres composta pelo nome do pacote e pelo nome da classe (consulte o exemplo a seguir). - Defina a
Permissionpropriedade noServiceAttributepara a cadeia de caracteresandroid.permission.BIND_JOB_SERVICE. - Substitua o
OnStartJobmétodo , adicionando o código para executar o trabalho. O Android invocará esse método no thread main do aplicativo para executar o trabalho. Trabalho que levará mais tempo para que alguns milissegundos sejam executados em um thread para evitar o bloqueio do aplicativo. - Quando o trabalho é feito, o
JobServicedeve chamar oJobFinishedmétodo . Esse método é comoJobServiceinforma que oJobSchedulertrabalho é feito. A falha na chamadaJobFinishedresultará naJobServicecolocação de demandas desnecessárias no dispositivo, reduzindo a duração da bateria. - É uma boa ideia também substituir o
OnStopJobmétodo . Esse método é chamado pelo Android quando o trabalho está sendo desligado antes de ser concluído e oferece aJobServiceoportunidade de descartar corretamente todos os recursos. Esse método deverá retornartruese for necessário reagendar o trabalho oufalsese não for desejável executar novamente o trabalho.
O código a seguir é um exemplo do mais simples JobService para um aplicativo, usando o TPL para executar de forma assíncrona algum trabalho:
[Service(Name = "com.xamarin.samples.downloadscheduler.DownloadJob",
Permission = "android.permission.BIND_JOB_SERVICE")]
public class DownloadJob : JobService
{
public override bool OnStartJob(JobParameters jobParams)
{
Task.Run(() =>
{
// Work is happening asynchronously
// Have to tell the JobScheduler the work is done.
JobFinished(jobParams, false);
});
// Return true because of the asynchronous work
return true;
}
public override bool OnStopJob(JobParameters jobParams)
{
// we don't want to reschedule the job if it is stopped or cancelled.
return false;
}
}
Criando um JobInfo para agendar um trabalho
Os aplicativos Xamarin.Android não instanciam um JobService diretamente, em vez disso, passarão um JobInfo objeto para o JobScheduler. O JobScheduler criará uma instância do objeto solicitado JobService , agendando e executando o JobService de acordo com os metadados no JobInfo. Um JobInfo objeto deve conter as seguintes informações:
- JobId – esse é um
intvalor usado para identificar um trabalho para oJobScheduler. Reutilizá-lo atualizará todos os trabalhos existentes. O valor deve ser exclusivo para o aplicativo. - JobService – esse parâmetro é um
ComponentNameque identifica explicitamente o tipo que oJobSchedulerdeve usar para executar um trabalho.
Este método de extensão demonstra como criar um com um JobInfo.Builder Android Context, como uma Atividade:
public static class JobSchedulerHelpers
{
public static JobInfo.Builder CreateJobBuilderUsingJobId<T>(this Context context, int jobId) where T:JobService
{
var javaClass = Java.Lang.Class.FromType(typeof(T));
var componentName = new ComponentName(context, javaClass);
return new JobInfo.Builder(jobId, componentName);
}
}
// Sample usage - creates a JobBuilder for a DownloadJob and sets the Job ID to 1.
var jobBuilder = this.CreateJobBuilderUsingJobId<DownloadJob>(1);
var jobInfo = jobBuilder.Build(); // creates a JobInfo object.
Um recurso avançado do Agendador de Trabalhos do Android é a capacidade de controlar quando um trabalho é executado ou em quais condições um trabalho pode ser executado. A tabela a seguir descreve alguns dos métodos em JobInfo.Builder que permitem que um aplicativo influencie quando um trabalho pode ser executado:
| Método | Descrição |
|---|---|
SetMinimumLatency |
Especifica que um atraso (em milissegundos) que deve ser observado antes de um trabalho ser executado. |
SetOverridingDeadline |
Declara que o trabalho deve ser executado antes dessa vez (em milissegundos) ter decorrido. |
SetRequiredNetworkType |
Especifica os requisitos de rede para um trabalho. |
SetRequiresBatteryNotLow |
O trabalho só poderá ser executado quando o dispositivo não estiver exibindo um aviso de "bateria baixa" para o usuário. |
SetRequiresCharging |
O trabalho só pode ser executado quando a bateria está carregando. |
SetDeviceIdle |
O trabalho será executado quando o dispositivo estiver ocupado. |
SetPeriodic |
Especifica que o trabalho deve ser executado regularmente. |
SetPersisted |
O trabalho deve perisistá-lo entre reinicializações de dispositivo. |
O SetBackoffCriteria fornece algumas diretrizes sobre quanto tempo o JobScheduler deve esperar antes de tentar executar um trabalho novamente. Há duas partes para os critérios de retirada: um atraso em milissegundos (valor padrão de 30 segundos) e um tipo de retirada que deve ser usado (às vezes chamado de política de retirada ou política de repetição). As duas políticas são encapsuladas na Android.App.Job.BackoffPolicy enumeração :
BackoffPolicy.Exponential– Uma política de retirada exponencial aumentará o valor de retirada inicial exponencialmente após cada falha. Na primeira vez que um trabalho falhar, a biblioteca aguardará o intervalo inicial especificado antes de reagendar o trabalho – exemplo, 30 segundos. Na segunda vez que o trabalho falhar, a biblioteca aguardará pelo menos 60 segundos antes de tentar executar o trabalho. Após a terceira tentativa com falha, a biblioteca aguardará 120 segundos e assim por diante. Esse é o valor padrão.BackoffPolicy.Linear– Essa estratégia é uma retirada linear que o trabalho deve ser reagendado para ser executado em intervalos definidos (até que seja bem-sucedido). A retirada linear é mais adequada para o trabalho que deve ser concluído o mais rápido possível ou para problemas que rapidamente se resolve.
Para obter mais detalhes sobre como criar um JobInfo objeto, leia a documentação do Google para a JobInfo.Builder classe .
Passando parâmetros para um trabalho por meio do JobInfo
Os parâmetros são passados para um trabalho criando um PersistableBundle que é passado junto com o Job.Builder.SetExtras método :
var jobParameters = new PersistableBundle();
jobParameters.PutInt("LoopCount", 11);
var jobBuilder = this.CreateJobBuilderUsingJobId<DownloadJob>(1)
.SetExtras(jobParameters)
.Build();
O PersistableBundle é acessado da Android.App.Job.JobParameters.Extras propriedade no OnStartJob método de um JobService:
public override bool OnStartJob(JobParameters jobParameters)
{
var loopCount = jobParams.Extras.GetInt("LoopCount", 10);
// rest of code omitted
}
Agendando um trabalho
Para agendar um trabalho, um aplicativo Xamarin.Android obterá uma referência ao serviço do JobScheduler sistema e chamará o JobScheduler.Schedule método com o JobInfo objeto que foi criado na etapa anterior. JobScheduler.Schedule retornará imediatamente com um dos dois valores inteiros:
- JobScheduler.ResultSuccess – O trabalho foi agendado com êxito.
- JobScheduler.ResultFailure – O trabalho não pôde ser agendado. Normalmente, isso é causado por parâmetros conflitantes
JobInfo.
Esse código é um exemplo de agendamento de um trabalho e notificar o usuário sobre os resultados da tentativa de agendamento:
var jobScheduler = (JobScheduler)GetSystemService(JobSchedulerService);
var scheduleResult = jobScheduler.Schedule(jobInfo);
if (JobScheduler.ResultSuccess == scheduleResult)
{
var snackBar = Snackbar.Make(FindViewById(Android.Resource.Id.Content), Resource.String.jobscheduled_success, Snackbar.LengthShort);
snackBar.Show();
}
else
{
var snackBar = Snackbar.Make(FindViewById(Android.Resource.Id.Content), Resource.String.jobscheduled_failure, Snackbar.LengthShort);
snackBar.Show();
}
Cancelando um trabalho
É possível cancelar todos os trabalhos que foram agendados ou apenas um único trabalho usando o JobsScheduler.CancelAll() método ou o JobScheduler.Cancel(jobId) método :
// Cancel all jobs
jobScheduler.CancelAll();
// to cancel a job with jobID = 1
jobScheduler.Cancel(1)
Resumo
Este guia discutiu como usar o Agendador de Trabalho do Android para executar o trabalho de forma inteligente em segundo plano. Ele discutiu como encapsular o trabalho a ser executado como um JobService e como usar o JobScheduler para agendar esse trabalho, especificando os critérios com um JobTrigger e como as falhas devem ser tratadas com um RetryStrategy.