Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa guida illustra come pianificare il lavoro in background usando l'API Dell'utilità di pianificazione processi Android, disponibile nei dispositivi Android che eseguono Android 5.0 (livello API 21) e versioni successive.
Panoramica
Uno dei modi migliori per mantenere reattiva un'applicazione Android all'utente consiste nel garantire che il lavoro complesso o a esecuzione prolungata venga eseguito in background. Tuttavia, è importante che il lavoro in background non influisca negativamente sull'esperienza dell'utente con il dispositivo.
Ad esempio, un processo in background potrebbe eseguire il polling di un sito Web ogni tre o quattro minuti per eseguire una query per le modifiche apportate a un determinato set di dati. Questo sembra benigno, tuttavia avrebbe un impatto disastroso sulla durata della batteria. L'applicazione riattiva ripetutamente il dispositivo, eleva la CPU a uno stato di alimentazione superiore, accende le radio, effettua le richieste di rete e quindi elabora i risultati. Peggiora perché il dispositivo non si spegne immediatamente e torna allo stato di inattività a basso consumo. Il lavoro in background pianificato in modo non adeguato può inavvertitamente mantenere il dispositivo in uno stato con requisiti di alimentazione non necessari ed eccessivi. Questa attività apparentemente innocente (polling di un sito Web) rende il dispositivo inutilizzabile in un periodo di tempo relativamente breve.
Android fornisce le API seguenti per facilitare l'esecuzione del lavoro in background, ma da soli non sono sufficienti per la pianificazione intelligente dei processi.
- Servizi finalità: i servizi finalità sono ideali per l'esecuzione del lavoro, ma non consentono di pianificare il lavoro.
- AlarmManager : queste API consentono solo di pianificare il lavoro, ma non consentono di eseguire effettivamente il lavoro. Inoltre, AlarmManager consente solo vincoli basati sul tempo, il che significa generare un allarme in un determinato momento o dopo un determinato periodo di tempo è trascorso.
- Ricevitori di trasmissione: un'app Android può configurare ricevitori di trasmissione per eseguire operazioni in risposta a eventi o finalità a livello di sistema. Tuttavia, i ricevitori di trasmissione non forniscono alcun controllo su quando deve essere eseguito il processo. Inoltre, le modifiche apportate al sistema operativo Android limiteranno quando i ricevitori di trasmissione funzioneranno o i tipi di lavoro a cui possono rispondere.
Esistono due funzionalità chiave per eseguire in modo efficiente il lavoro in background (talvolta definito processo in background o processo):
- Pianificazione intelligente del lavoro : è importante che quando un'applicazione esegue il lavoro in background che lo fa come un buon cittadino. Idealmente, l'applicazione non deve richiedere l'esecuzione di un processo. L'applicazione deve invece specificare le condizioni che devono essere soddisfatte per quando il processo può essere eseguito e quindi pianificare il processo con il sistema operativo che eseguirà il lavoro quando vengono soddisfatte le condizioni. In questo modo Android può eseguire il processo per garantire la massima efficienza nel dispositivo. Ad esempio, le richieste di rete possono essere raggruppate per l'esecuzione contemporaneamente per sfruttare al massimo il sovraccarico necessario per la rete.
- Incapsulamento del lavoro : il codice per eseguire il lavoro in background deve essere incapsulato in un componente discreto che può essere eseguito indipendentemente dall'interfaccia utente e sarà relativamente facile da riprogrammare se il lavoro non viene completato per qualche motivo.
L'Utilità di pianificazione processi Android è un framework integrato nel sistema operativo Android che fornisce un'API Fluent per semplificare la pianificazione del lavoro in background. L'Utilità di pianificazione processi Android è costituita dai tipi seguenti:
Android.App.Job.JobSchedulerè un servizio di sistema usato per pianificare, eseguire e, se necessario, annullare i processi per conto di un'applicazione Android.- È
Android.App.Job.JobServiceuna classe astratta che deve essere estesa con la logica che eseguirà il processo nel thread principale dell'applicazione. Ciò significa che èJobServiceresponsabile del modo in cui il lavoro deve essere eseguito in modo asincrono. - Un
Android.App.Job.JobInfooggetto contiene i criteri per guidare Android quando il processo deve essere eseguito.
Per pianificare l'uso dell'Utilità di pianificazione processi Android, un'applicazione Xamarin.Android deve incapsulare il codice in una classe che estende la JobService classe . JobService ha tre metodi del ciclo di vita che possono essere chiamati durante la durata del processo:
bool OnStartJob(Parametri JobParameters): questo metodo viene chiamato da
JobSchedulerper eseguire il lavoro ed eseguito sul thread principale dell'applicazione. È responsabilità dell'utenteJobServiceeseguire in modo asincrono il lavoro e restituiretruese è presente un lavoro rimanente ofalsese il lavoro viene eseguito.Quando chiama
JobSchedulerquesto metodo, richiederà e manterrà un wakelock da Android per la durata del processo. Al termine del processo, è responsabilità dell'utenteJobServiceindicare questoJobSchedulerfatto chiamando ilJobFinishedmetodo (descritto di seguito).JobFinished(Parametri JobParameters, bool needsReschedule): questo metodo deve essere chiamato da
JobServiceper indicareJobSchedulerche il lavoro è stato eseguito. SeJobFinishednon viene chiamato, ilJobSchedulernon rimuoverà il wakelock, causando inutili scaricamento della batteria.bool OnStopJob(Parametri JobParameters): viene chiamato quando il processo viene arrestato prematuramente da Android. Deve restituire
truese il processo deve essere riprogrammato in base ai criteri di ripetizione dei tentativi (descritti di seguito in modo più dettagliato).
È possibile specificare vincoli o trigger che controllano quando un processo può o deve essere eseguito. Ad esempio, è possibile vincolare un processo in modo che venga eseguito solo quando il dispositivo viene ricaricato o per avviare un processo quando viene scattata un'immagine.
Questa guida illustra in dettaglio come implementare una JobService classe e pianificarla con .JobScheduler
Requisiti
L'Utilità di pianificazione processi Android richiede il livello API Android 21 (Android 5.0) o versione successiva.
Uso dell'utilità di pianificazione dei processi Android
Esistono tre passaggi per l'uso dell'API JobScheduler Android:
- Implementare un tipo JobService per incapsulare il lavoro.
- Utilizzare un
JobInfo.Builderoggetto per creare l'oggettoJobInfoche conterrà i criteri per l'esecuzioneJobSchedulerdel processo. - Pianificare il processo usando
JobScheduler.Schedule.
Implementare un jobService
Tutte le operazioni eseguite dalla libreria dell'Utilità di pianificazione processi Android devono essere eseguite in un tipo che estende la Android.App.Job.JobService classe astratta. La creazione di un JobService oggetto è molto simile alla creazione di un Service con il framework Android:
- Estendere la classe
JobService. - Decorare la sottoclasse con
ServiceAttributee impostare ilNameparametro su una stringa costituita dal nome del pacchetto e dal nome della classe (vedere l'esempio seguente). - Impostare la
Permissionproprietà sull'oggettoServiceAttributesulla stringaandroid.permission.BIND_JOB_SERVICE. - Eseguire l'override del
OnStartJobmetodo aggiungendo il codice per eseguire il lavoro. Android richiamerà questo metodo sul thread principale dell'applicazione per eseguire il processo. Il lavoro che richiederà più tempo per alcuni millisecondi deve essere eseguito su un thread per evitare di bloccare l'applicazione. - Al termine del lavoro, deve
JobServicechiamare ilJobFinishedmetodo . Questo metodo indicaJobServiceche ilJobSchedulerlavoro viene eseguito. La mancata chiamataJobFinishedcomporterà l'inserimentoJobServicedi richieste non necessarie sul dispositivo, riducendo la durata della batteria. - È consigliabile eseguire anche l'override del
OnStopJobmetodo . Questo metodo viene chiamato da Android quando il processo viene arrestato prima del completamento e offre laJobServicepossibilità di eliminare correttamente le risorse. Questo metodo deve restituiretruese è necessario riprogrammare il processo ofalsese non è consigliabile eseguire nuovamente il processo.
Il codice seguente è un esempio del più semplice JobService per un'applicazione, usando il TPL per eseguire in modo asincrono alcune operazioni:
[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;
}
}
Creazione di un elemento JobInfo per pianificare un processo
Le applicazioni Xamarin.Android non creano un'istanza diretta di , JobService ma passano un JobInfo oggetto a JobScheduler. Verrà JobScheduler creata un'istanza dell'oggetto richiesto JobService , della pianificazione e dell'esecuzione di JobService in base ai metadati in JobInfo. Un JobInfo oggetto deve contenere le informazioni seguenti:
- JobId : valore
intusato per identificare un processo inJobScheduler. Il riutilizzo di questo valore aggiornerà tutti i processi esistenti. Il valore deve essere univoco per l'applicazione. - JobService : questo parametro è un
ComponentNameoggetto che identifica in modo esplicito il tipo daJobSchedulerusare per eseguire un processo.
Questo metodo di estensione illustra come creare un JobInfo.Builder oggetto con un oggetto Android Context, ad esempio un'attività:
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.
Una potente funzionalità dell'Utilità di pianificazione processi Android è la possibilità di controllare quando un processo viene eseguito o in quali condizioni può essere eseguito un processo. La tabella seguente descrive alcuni dei metodi su JobInfo.Builder che consentono a un'app di influenzare quando un processo può essere eseguito:
| metodo | Descrizione |
|---|---|
SetMinimumLatency |
Specifica che un ritardo (in millisecondi) che deve essere osservato prima dell'esecuzione di un processo. |
SetOverridingDeadline |
Dichiara che il processo deve essere eseguito prima che sia trascorso questo tempo (in millisecondi). |
SetRequiredNetworkType |
Specifica i requisiti di rete per un processo. |
SetRequiresBatteryNotLow |
Il processo può essere eseguito solo quando il dispositivo non visualizza un avviso di "batteria insufficiente" all'utente. |
SetRequiresCharging |
Il processo può essere eseguito solo quando la batteria è carica. |
SetDeviceIdle |
Il processo verrà eseguito quando il dispositivo è occupato. |
SetPeriodic |
Specifica che il processo deve essere eseguito regolarmente. |
SetPersisted |
Il processo deve essere perisist tra i riavvii del dispositivo. |
SetBackoffCriteria Fornisce alcune indicazioni su quanto tempo JobScheduler deve attendere prima di provare a eseguire di nuovo un processo. Esistono due parti dei criteri di backoff: un ritardo in millisecondi (valore predefinito di 30 secondi) e tipo di backoff da usare (talvolta definito criterio di backoff o criteri di ripetizione dei tentativi). I due criteri sono incapsulati nell'enumerazione Android.App.Job.BackoffPolicy :
BackoffPolicy.Exponential: un criterio di backoff esponenziale aumenterà il valore di backoff iniziale in modo esponenziale dopo ogni errore. La prima volta che un processo ha esito negativo, la libreria attenderà l'intervallo iniziale specificato prima di riprogrammare il processo, ad esempio 30 secondi. La seconda volta che il processo ha esito negativo, la libreria attenderà almeno 60 secondi prima di provare a eseguire il processo. Dopo il terzo tentativo non riuscito, la libreria attenderà 120 secondi e così via. Questo è il valore predefinito.BackoffPolicy.Linear: questa strategia è un backoff lineare che il processo deve essere riprogrammato per l'esecuzione a intervalli impostati (fino a quando non riesce). Il backoff lineare è più adatto per il lavoro che deve essere completato il prima possibile o per i problemi che si risolvono rapidamente.
Per altri dettagli sulla creazione di un JobInfo oggetto, leggere la documentazione di Google per la JobInfo.Builder classe.
Passaggio di parametri a un processo tramite JobInfo
I parametri vengono passati a un processo creando un PersistableBundle oggetto passato insieme al Job.Builder.SetExtras metodo :
var jobParameters = new PersistableBundle();
jobParameters.PutInt("LoopCount", 11);
var jobBuilder = this.CreateJobBuilderUsingJobId<DownloadJob>(1)
.SetExtras(jobParameters)
.Build();
L'oggetto PersistableBundleAndroid.App.Job.JobParameters.Extras è accessibile dalla proprietà nel OnStartJob metodo di un JobServiceoggetto :
public override bool OnStartJob(JobParameters jobParameters)
{
var loopCount = jobParams.Extras.GetInt("LoopCount", 10);
// rest of code omitted
}
Programmazione di un processo
Per pianificare un processo, un'applicazione Xamarin.Android otterrà un riferimento al JobScheduler servizio di sistema e chiamerà il JobScheduler.Schedule metodo con l'oggetto JobInfo creato nel passaggio precedente. JobScheduler.Schedule restituirà immediatamente con uno dei due valori integer:
- JobScheduler.ResultSuccess : il processo è stato pianificato correttamente.
- JobScheduler.ResultFailure : impossibile pianificare il processo. Questo è in genere causato da parametri in conflitto
JobInfo.
Questo codice è un esempio di pianificazione di un processo e notifica all'utente dei risultati del tentativo di pianificazione:
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();
}
Annullamento di un processo
È possibile annullare tutti i processi pianificati o solo un singolo processo usando il JobsScheduler.CancelAll() metodo o il JobScheduler.Cancel(jobId) metodo :
// Cancel all jobs
jobScheduler.CancelAll();
// to cancel a job with jobID = 1
jobScheduler.Cancel(1)
Riepilogo
Questa guida ha illustrato come usare l'Utilità di pianificazione processi Android per eseguire in modo intelligente il lavoro in background. Ha illustrato come incapsulare il lavoro da eseguire come e JobService come usare JobScheduler per pianificare il lavoro, specificando i criteri con un JobTrigger e come gestire gli errori con un oggetto RetryStrategy.