Android-Auftragsplaner
In diesem Leitfaden wird erläutert, wie Sie Hintergrundarbeiten mit der Android-Auftragsplanungs-API planen, die auf Android-Geräten mit Android 5.0 (API-Ebene 21) und höher verfügbar ist.
Übersicht
Eine der besten Möglichkeiten, um eine Android-Anwendung auf den Benutzer reagieren zu lassen, besteht darin, sicherzustellen, dass komplexe oder lang andauernde Arbeiten im Hintergrund ausgeführt werden. Es ist jedoch wichtig, dass sich Hintergrundarbeit nicht negativ auf die Benutzerfreundlichkeit mit dem Gerät auswirkt.
Beispielsweise kann ein Hintergrundauftrag alle drei oder vier Minuten eine Website abfragen, um Änderungen an einem bestimmten Dataset abzufragen. Dies scheint gut zu sein, hätte jedoch eine katastrophale Auswirkung auf die Akkulaufzeit. Die Anwendung wird das Gerät wiederholt reaktivieren, die CPU in einen höheren Leistungszustand versetzen, die Funkgeräte einschalten, netzwerkanforderungen stellen und dann die Ergebnisse verarbeiten. Es wird schlimmer, da das Gerät nicht sofort heruntergefahren wird und in den Leerlaufzustand mit geringer Leistung zurückkehrt. Schlecht geplante Hintergrundarbeit kann das Gerät versehentlich in einem Zustand mit unnötigen und übermäßigen Stromanforderungen halten. Diese scheinbar unschuldige Aktivität (Das Abrufen einer Website) wird das Gerät in relativ kurzer Zeit unbrauchbar machen.
Android stellt die folgenden APIs bereit, um die Ausführung von Arbeiten im Hintergrund zu unterstützen, aber sie allein reichen für eine intelligente Auftragsplanung nicht aus.
- Absichtsdienste : Absichtsdienste eignen sich hervorragend für die Ausführung der Arbeit, bieten jedoch keine Möglichkeit, Die Arbeit zu planen.
- AlarmManager : Diese APIs ermöglichen nur die Planung der Arbeit, bieten jedoch keine Möglichkeit, die Arbeit tatsächlich auszuführen. Außerdem lässt der AlarmManager nur zeitbasierte Einschränkungen zu, was bedeutet, dass ein Alarm zu einem bestimmten Zeitpunkt oder nach Ablauf eines bestimmten Zeitraums ausgelöst wird.
- Broadcast Receivers : Eine Android-App kann Rundfunkempfänger einrichten, um Arbeiten als Reaktion auf systemweite Ereignisse oder Absichten auszuführen. Sendeempfänger bieten jedoch keine Kontrolle darüber, wann der Auftrag ausgeführt werden soll. Änderungen am Android-Betriebssystem schränken außerdem ein, wann Rundfunkempfänger funktionieren oder auf welche Arten von Aufgaben sie reagieren können.
Es gibt zwei wichtige Features für die effiziente Ausführung von Hintergrundarbeiten (manchmal auch als Hintergrundauftrag oder Auftrag bezeichnet):
- Intelligente Planung der Arbeit – Es ist wichtig, dass eine Anwendung, die im Hintergrund arbeitet, dies als guter Bürger tut. Im Idealfall sollte die Anwendung nicht verlangen, dass ein Auftrag ausgeführt wird. Stattdessen sollte die Anwendung Bedingungen angeben, die erfüllt werden müssen, wenn der Auftrag ausgeführt werden kann, und dann diesen Auftrag mit dem Betriebssystem planen, das die Arbeit ausführt, wenn die Bedingungen erfüllt sind. Dadurch kann Android den Auftrag ausführen, um eine maximale Effizienz auf dem Gerät zu gewährleisten. Netzwerkanforderungen können beispielsweise im Batch ausgeführt werden, um alle gleichzeitig auszuführen, um den mit dem Netzwerk verbundenen Mehraufwand maximal zu nutzen.
- Kapselung der Arbeit : Der Code zum Ausführen der Hintergrundarbeiten sollte in eine diskrete Komponente gekapselt werden, die unabhängig von der Benutzeroberfläche ausgeführt werden kann und relativ einfach neu geplant werden kann, wenn die Arbeit aus irgendeinem Grund nicht abgeschlossen werden kann.
Der Android-Auftragsplaner ist ein Framework, das in das Android-Betriebssystem integriert ist und eine Fluent-API bietet, um die Planung von Hintergrundarbeiten zu vereinfachen. Der Android-Auftragsplaner besteht aus den folgenden Typen:
- Der
Android.App.Job.JobScheduler
ist ein Systemdienst, der zum Planen, Ausführen und ggf. Abbrechen von Aufträgen im Auftrag einer Android-Anwendung verwendet wird. - Ein
Android.App.Job.JobService
ist eine abstrakte Klasse, die mit der Logik erweitert werden muss, die den Auftrag im Standard Thread der Anwendung ausführen wird. Dies bedeutet, dass derJobService
dafür verantwortlich ist, wie die Arbeit asynchron ausgeführt werden soll. - Ein
Android.App.Job.JobInfo
-Objekt enthält die Kriterien, die Android anleiten sollen, wann der Auftrag ausgeführt werden soll.
Um die Arbeit mit dem Android-Auftragsplaner zu planen, muss eine Xamarin.Android-Anwendung den Code in einer Klasse kapseln, die die JobService
Klasse erweitert. JobService
verfügt über drei Lebenszyklusmethoden, die während der Lebensdauer des Auftrags aufgerufen werden können:
bool OnStartJob(JobParameters parameters) – Diese Methode wird von aufgerufen
JobScheduler
, um Arbeiten auszuführen, und wird im Standard Thread der Anwendung ausgeführt. Es liegt in der Verantwortung desJobService
, die Arbeit asynchron auszuführen und zurückzugebentrue
, wenn noch Arbeit vorhanden ist oderfalse
wenn die Arbeit erledigt ist.Wenn diese
JobScheduler
Methode aufgerufen wird, wird ein Wakelock von Android für die Dauer des Auftrags gefordert und beibehalten. Wenn der Auftrag abgeschlossen ist, liegt es in der Verantwortung desJobService
, denJobScheduler
von dieser Tatsache zu informieren, indem sie dieJobFinished
-Methode aufrufen (weiter beschrieben).JobFinished(JobParameters-Parameter, bool needsReschedule) – Diese Methode muss von
JobService
aufgerufen werden, um mitzuteilenJobScheduler
, dass die Arbeit erledigt ist. WennJobFinished
nicht aufgerufen wird, wird derJobScheduler
Wakelock nicht entfernt, was zu unnötigem Akkuverbrauch führt.bool OnStopJob(JobParameters-Parameter): Dies wird aufgerufen, wenn der Auftrag von Android vorzeitig beendet wird. Es sollte zurückgegeben
true
werden, wenn der Auftrag basierend auf den Wiederholungskriterien (unten ausführlicher erläutert) neu geplant werden soll.
Es ist möglich, Einschränkungen oder Trigger anzugeben, die steuern, wann ein Auftrag ausgeführt werden kann oder soll. Beispielsweise ist es möglich, einen Auftrag so einzuschränken, dass er nur ausgeführt wird, wenn das Gerät aufgeladen wird, oder um einen Auftrag zu starten, wenn ein Bild aufgenommen wird.
In diesem Leitfaden wird ausführlich erläutert, wie eine JobService
Klasse implementiert und mit JobScheduler
dem geplant wird.
Anforderungen
Für den Android-Auftragsplaner ist die Android-API-Ebene 21 (Android 5.0) oder höher erforderlich.
Verwenden des Android-Auftragsplaner
Es gibt drei Schritte für die Verwendung der Android JobScheduler-API:
- Implementieren Sie einen JobService-Typ, um die Arbeit zu kapseln.
- Verwenden Sie ein
JobInfo.Builder
-Objekt, um dasJobInfo
-Objekt zu erstellen, das die Kriterien für dieJobScheduler
Ausführung des Auftrags enthält. - Planen Sie den Auftrag mit
JobScheduler.Schedule
.
Implementieren eines JobService
Alle von der Android Job Scheduler-Bibliothek ausgeführten Arbeiten müssen in einem Typ ausgeführt werden, der die Android.App.Job.JobService
abstrakte Klasse erweitert. Das Erstellen eines JobService
ähnelt dem Erstellen eines Service
mit dem Android-Framework:
- Erweitern Sie die
JobService
-Klasse. - Dekorieren Sie die Unterklasse mit dem
ServiceAttribute
, und legen Sie denName
Parameter auf eine Zeichenfolge fest, die aus dem Paketnamen und dem Namen der Klasse besteht (siehe das folgende Beispiel). - Legen Sie die
Permission
-Eigenschaft für aufServiceAttribute
die Zeichenfolgeandroid.permission.BIND_JOB_SERVICE
fest. - Überschreiben Sie die
OnStartJob
-Methode, und fügen Sie den Code hinzu, um die Arbeit auszuführen. Android ruft diese Methode im Standard Thread der Anwendung auf, um den Auftrag auszuführen. Arbeit, die länger dauert, als einige Millisekunden für einen Thread ausgeführt werden sollten, um eine Blockierung der Anwendung zu vermeiden. - Wenn die Arbeit erledigt ist, muss die
JobService
-JobFinished
Methode aufgerufen werden. Mit dieser Methode wirdJobService
mitgeteilt, dass dieJobScheduler
Arbeit erledigt ist. Ein NichtaufrufJobFinished
führtJobService
dazu, dass unnötige Anforderungen an das Gerät gestellt werden und die Akkulaufzeit verkürzt wird. - Es empfiehlt sich, die
OnStopJob
Methode auch außer Kraft zu setzen. Diese Methode wird von Android aufgerufen, wenn der Auftrag heruntergefahren wird, bevor er abgeschlossen ist, und bietet dieJobService
Möglichkeit, alle Ressourcen ordnungsgemäß zu entsorgen. Diese Methode sollte zurückgegebentrue
werden, wenn der Auftrag neu geplant werden muss oderfalse
wenn es nicht wünschenswert ist, den Auftrag erneut auszuführen.
Der folgende Code ist ein Beispiel für die einfachsten JobService
für eine Anwendung, die die TPL zum asynchronen Ausführen von Aufgaben verwendet:
[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;
}
}
Erstellen einer JobInfo zum Planen eines Auftrags
Xamarin.Android-Anwendungen instanziieren nicht direkt, JobService
sondern übergeben ein JobInfo
-Objekt an die JobScheduler
. Die JobScheduler
instanziieren das angeforderte JobService
Objekt, planen und ausführen den JobService
entsprechend den Metadaten in der JobInfo
. Ein JobInfo
-Objekt muss die folgenden Informationen enthalten:
- JobId : Dies ist ein
int
Wert, der verwendet wird, um einen Auftrag für zuJobScheduler
identifizieren. Durch die Wiederverwendung dieses Werts werden alle vorhandenen Aufträge aktualisiert. Der Wert muss für die Anwendung eindeutig sein. - JobService : Dieser Parameter identifiziert
ComponentName
explizit den Typ, derJobScheduler
zum Ausführen eines Auftrags verwendet werden soll.
Mit dieser Erweiterungsmethode wird veranschaulicht, wie sie JobInfo.Builder
mit einem Android-Gerät Context
erstellt werden, z. B. eine Aktivität:
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.
Ein leistungsstarkes Feature des Android-Auftragsplaner ist die Möglichkeit zu steuern, wann ein Auftrag ausgeführt wird oder unter welchen Bedingungen ein Auftrag ausgeführt werden kann. In der folgenden Tabelle werden einige der Methoden JobInfo.Builder
beschrieben, mit denen eine App beeinflussen kann, wann ein Auftrag ausgeführt werden kann:
Methode | BESCHREIBUNG |
---|---|
SetMinimumLatency |
Gibt an, dass eine Verzögerung (in Millisekunden) beobachtet werden soll, bevor ein Auftrag ausgeführt wird. |
SetOverridingDeadline |
Deklariert, dass der Auftrag ausgeführt werden muss, bevor diese Zeit (in Millisekunden) verstrichen ist. |
SetRequiredNetworkType |
Gibt die Netzwerkanforderungen für einen Auftrag an. |
SetRequiresBatteryNotLow |
Der Auftrag kann nur ausgeführt werden, wenn das Gerät dem Benutzer keine Warnung "Akkustand" anzeigt. |
SetRequiresCharging |
Der Auftrag kann nur ausgeführt werden, wenn der Akku aufgeladen wird. |
SetDeviceIdle |
Der Auftrag wird ausgeführt, wenn das Gerät ausgelastet ist. |
SetPeriodic |
Gibt an, dass der Auftrag regelmäßig ausgeführt werden soll. |
SetPersisted |
Der Auftrag sollte über Geräteneustarts hinweg ausgeführt werden. |
Der SetBackoffCriteria
enthält eine Anleitung dazu, wie lange die JobScheduler
warten sollte, bevor sie versuchen, einen Auftrag erneut auszuführen. Es gibt zwei Teile der Backoffkriterien: eine Verzögerung in Millisekunden (Standardwert von 30 Sekunden) und den Typ des Backoffs, der verwendet werden soll (manchmal auch als Backoffrichtlinie oder Wiederholungsrichtlinie bezeichnet). Die beiden Richtlinien sind in der Android.App.Job.BackoffPolicy
Aufzählung gekapselt:
BackoffPolicy.Exponential
– Eine exponentielle Backoffrichtlinie erhöht den anfänglichen Backoffwert nach jedem Fehler exponentiell. Wenn ein Auftrag zum ersten Mal fehlschlägt, wartet die Bibliothek das angegebene anfangs angegebene Intervall, bevor der Auftrag neu geplant wird ( Beispiel 30 Sekunden). Wenn der Auftrag zum zweiten Mal fehlschlägt, wartet die Bibliothek mindestens 60 Sekunden, bevor sie versucht, den Auftrag auszuführen. Nach dem dritten fehlgeschlagenen Versuch wartet die Bibliothek 120 Sekunden usw. Dies ist der Standardwert.BackoffPolicy.Linear
– Diese Strategie ist ein linearer Backoff, bei dem der Auftrag neu geplant werden sollte, um in festgelegten Intervallen ausgeführt zu werden (bis er erfolgreich ist). Linearer Backoff eignet sich am besten für Arbeiten, die so schnell wie möglich abgeschlossen werden müssen, oder für Probleme, die sich schnell beheben lassen.
Weitere Informationen zum Erstellen eines JobInfo
Objekts finden Sie in der Google-Dokumentation für die JobInfo.Builder
Klasse.
Übergeben von Parametern an einen Auftrag über jobInfo
Parameter werden an einen Auftrag übergeben, indem ein PersistableBundle
erstellt wird, das zusammen mit der Job.Builder.SetExtras
-Methode übergeben wird:
var jobParameters = new PersistableBundle();
jobParameters.PutInt("LoopCount", 11);
var jobBuilder = this.CreateJobBuilderUsingJobId<DownloadJob>(1)
.SetExtras(jobParameters)
.Build();
Auf PersistableBundle
wird über die Android.App.Job.JobParameters.Extras
-Eigenschaft in der OnStartJob
-Methode eines JobService
zugegriffen:
public override bool OnStartJob(JobParameters jobParameters)
{
var loopCount = jobParams.Extras.GetInt("LoopCount", 10);
// rest of code omitted
}
Planen eines Auftrags
Um einen Auftrag zu planen, ruft eine Xamarin.Android-Anwendung einen Verweis auf den JobScheduler
Systemdienst ab und ruft die Methode mit dem JobScheduler.Schedule
JobInfo
Objekt auf, das im vorherigen Schritt erstellt wurde. JobScheduler.Schedule
wird sofort mit einem von zwei ganzzahligen Werten zurückgegeben:
- JobScheduler.ResultSuccess : Der Auftrag wurde erfolgreich geplant.
- JobScheduler.ResultFailure : Der Auftrag konnte nicht geplant werden. Dies wird in der Regel durch in Konflikt stehende
JobInfo
Parameter verursacht.
Dieser Code ist ein Beispiel für die Planung eines Auftrags und die Benachrichtigung des Benutzers über die Ergebnisse des Planungsversuchs:
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();
}
Abbrechen eines Auftrags
Es ist möglich, alle geplanten Aufträge oder nur einen einzelnen Auftrag mit der JobsScheduler.CancelAll()
-Methode oder der JobScheduler.Cancel(jobId)
-Methode abzubrechen:
// Cancel all jobs
jobScheduler.CancelAll();
// to cancel a job with jobID = 1
jobScheduler.Cancel(1)
Zusammenfassung
In diesem Leitfaden wurde erläutert, wie Sie den Android-Auftragsplaner verwenden, um Arbeiten im Hintergrund intelligent auszuführen. Es wurde erläutert, wie sie die auszuführende JobService
Arbeit kapseln und verwenden, um diese JobScheduler
Arbeit zu planen, wobei die Kriterien mit einem JobTrigger
angegeben werden und wie Fehler mit einem RetryStrategy
behandelt werden sollen.