Firebase 工作發送器
本指南討論如何使用Google的Firebase工作發送器連結庫排程背景工作。
概觀
讓Android應用程式對使用者保持回應的最佳方式之一,是確保背景中執行複雜或長時間執行的工作。 不過,背景工作不會對使用者使用裝置的體驗造成負面影響。
例如,背景作業可能會每隔三到四分鐘輪詢網站,以查詢特定數據集的變更。 這似乎是良性的,但它會對電池使用時間產生災難性的影響。 應用程式會重複喚醒裝置、將CPU提升至較高的電源狀態、啟動無線電、提出網路要求,然後處理結果。 情況變得更糟,因為裝置不會立即關閉電源,並返回低功率閑置狀態。 排程不佳的背景工作可能會不小心讓裝置處於不必要和過度電源需求的狀態。 這種看似無辜的活動(輪詢網站)將使裝置在相對短時間內無法使用。
Android 提供下列 API 來協助在背景中執行工作,但本身不足以進行智慧型手機工作排程。
- 意圖服務 – 意圖服務 非常適合執行工作,但無法排程工作。
- AlarmManager – 這些 API 只允許排程工作,但無法實際執行工作。 此外,AlarmManager 只允許以時間為基礎的條件約束,這表示在特定時間或經過一段時間之後引發警示。
- JobScheduler – JobSchedule 是一個絕佳的 API,可搭配操作系統排程作業。 不過,它僅適用於以 API 層級 21 或更新版本為目標的 Android 應用程式。
- 廣播接收者 – Android 應用程式可以設定廣播接收者,以執行工作以回應全系統事件或意圖。 不過,廣播接收器不會提供應該執行作業時的任何控制權。 Android 作業系統中的變更也會限制廣播接收者何時能夠運作,或可回應的工作種類。
有兩個主要功能可以有效率地執行背景工作(有時稱為背景工作或工作):
- 以智慧方式排程工作 – 當應用程式在背景中執行做為良好公民的工作時,這一點很重要。 在理想情況下,應用程式不應該要求執行作業。 相反地,應用程式應該指定在作業可以執行時必須符合的條件,然後排程該工作在符合條件時執行。 這可讓Android以智慧方式執行工作。 例如,網路要求可能會批處理以同時執行,以充分利用與網路相關的額外負荷。
- 封裝工作 – 執行背景工作 的程式代碼應該封裝在獨立於使用者介面獨立執行的離散元件中,如果工作因為某些原因而無法完成,則比較容易重新排程。
Firebase 作業發送器是 Google 的連結庫,可提供 Fluent API 來簡化排程背景工作。 它打算取代Google Cloud Manager。 Firebase 作業發送器包含下列 API:
Firebase.JobDispatcher.JobService
是一個抽象類,必須使用將在背景作業中執行的邏輯來擴充。- 宣告
Firebase.JobDispatcher.JobTrigger
何時應該啟動作業。 這通常以時間範圍表示,例如,在啟動作業之前至少等候 30 秒,但在 5 分鐘內執行作業。 Firebase.JobDispatcher.RetryStrategy
包含當作業無法正確執行時應該執行的動作相關信息。 重試策略會指定在嘗試再次執行作業之前要等候的時間長度。Firebase.JobDispatcher.Constraint
是選擇性值,描述作業執行之前必須符合的條件,例如裝置位於未計量的網路或充電上。Firebase.JobDispatcher.Job
是一種 API,可將 先前的 API 統一到 可由 排程JobDispatcher
的工作單位。 類別Job.Builder
是用來具現化Job
。Firebase.JobDispatcher.JobDispatcher
會使用前三個 API 來排程作業系統的工作,並在必要時提供取消作業的方式。
若要排程使用 Firebase 作業發送器,Xamarin.Android 應用程式必須將程式代碼封裝在擴充 JobService
類別的類型中。 JobService
有三種生命週期方法,可在作業存留期期間呼叫:
bool OnStartJob(IJobParameters parameters)
– 此方法是工作會發生的地方,而且應該一律實作。 它會在主線程上執行。 如果剩餘工時,或false
工作完成,這個方法會傳回true
。bool OnStopJob(IJobParameters parameters)
– 當作業因為某些原因而停止時,就會呼叫此作業。 如果應該重新排程工作以供稍後使用,則應該傳回true
。JobFinished(IJobParameters parameters, bool needsReschedule)
– 當 完成任何異步工作時JobService
,就會呼叫這個方法。
若要排程作業,應用程式會具現化 JobDispatcher
物件。 然後, Job.Builder
會用來建立 Job
物件,此物件會提供給 JobDispatcher
,以嘗試並排程要執行的作業。
本指南將討論如何將 Firebase 作業發送器新增至 Xamarin.Android 應用程式,並用它來排程背景工作。
需求
Firebase 作業發送器需要 Android API 層級 9 或更高版本。 Firebase 作業發送器連結庫依賴 Google Play Services 所提供的一些元件;裝置必須已安裝Google Play服務。
在 Xamarin.Android 中使用 Firebase 作業發送器連結庫
若要開始使用 Firebase 作業發送器,請先將 Xamarin.Firebase.JobDispatcher NuGet 套件新增至 Xamarin.Android 專案。 搜尋 NuGet 封裝管理員 以取得 Xamarin.Firebase.JobDispatcher 套件(仍在發行前版本)。
新增 Firebase 作業發送器連結庫之後,請建立類別 JobService
,然後排程它以 實例 FirebaseJobDispatcher
執行。
建立 JobService
Firebase 作業發送器連結庫所執行的所有工作,都必須在擴充 Firebase.JobDispatcher.JobService
抽象類的類型中完成。 JobService
建立 與使用 Android 架構建立 Service
非常類似:
- 擴充 類別
JobService
- 使用
ServiceAttribute
裝飾子類別。 雖然並非絕對必要,但建議明確設定Name
參數,以協助偵錯JobService
。 - 新增 以
IntentFilter
在 AndroidManifest.xml 中宣告JobService
。 這也有助於 Firebase 作業發送器連結庫找出並叫JobService
用 。
下列程式代碼是應用程式最簡單的 JobService
範例,使用 TPL 以異步方式執行某些工作:
[Service(Name = "com.xamarin.fjdtestapp.DemoJob")]
[IntentFilter(new[] {FirebaseJobServiceIntent.Action})]
public class DemoJob : JobService
{
static readonly string TAG = "X:DemoService";
public override bool OnStartJob(IJobParameters jobParameters)
{
Task.Run(() =>
{
// Work is happening asynchronously (code omitted)
});
// Return true because of the asynchronous work
return true;
}
public override bool OnStopJob(IJobParameters jobParameters)
{
Log.Debug(TAG, "DemoJob::OnStartJob");
// nothing to do.
return false;
}
}
建立 FirebaseJobDispatcher
在排程任何工作之前,必須先建立 Firebase.JobDispatcher.FirebaseJobDispatcher
物件。 FirebaseJobDispatcher
負責排程 JobService
。 下列代碼段是建立 實例的 FirebaseJobDispatcher
其中一種方式:
// This is the "Java" way to create a FirebaseJobDispatcher object
IDriver driver = new GooglePlayDriver(context);
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);
在先前的代碼段中, GooglePlayDriver
is 類別可協助 FirebaseJobDispatcher
與裝置上 Google Play Services 中的某些排程 API 互動。 參數 context
是任何 Android Context
,例如 Activity。 GooglePlayDriver
目前是 Firebase 作業發送器連結庫中唯一IDriver
的實作。
Firebase 作業發送器 Xamarin.Android 系結提供擴充方法,從 Context
建立 FirebaseJobDispatcher
:
FirebaseJobDispatcher dispatcher = context.CreateJobDispatcher();
FirebaseJobDispatcher
具現化之後,就可以在 類別中JobService
建立Job
並執行程序代碼。 Job
是由 Job.Builder
物件所建立,將在下一節中討論。
使用 Job.Builder 建立 Firebase.JobDispatcher.Job
類別 Firebase.JobDispatcher.Job
負責封裝執行 JobService
所需的元數據。 Job
包含的資訊,例如作業在執行之前必須符合的任何條件約束、如果 Job
為週期性,或會導致作業執行的任何觸發程式。 至少,Job
必須有標記(唯一的字串,可識別作業至 FirebaseJobDispatcher
的 ),以及應該執行的 型JobService
別。 Firebase 作業傳送器會在作業執行時具現化 JobService
。 Job
使用 類別的Firebase.JobDispatcher.Job.JobBuilder
實體建立 。
下列代碼段是如何使用 Xamarin.Android 系結建立 Job
的最簡單範例:
Job myJob = dispatcher.NewJobBuilder()
.SetService<DemoJob>("demo-job-tag")
.Build();
Job.Builder
將會對作業的輸入值執行一些基本驗證檢查。 如果 無法 Job.Builder
建立 ,將會擲回例外狀況 Job
。 Job.Builder
使用下列預設值建立 Job
:
Job
的存留期(將排程執行的時間)只有在裝置重新啟動後才會重新啟動, 一旦裝置重新啟動,就會Job
遺失。Job
不是週期性, 只會執行一次。Job
將排定儘快執行 。- 的預設重試策略
Job
是使用指數輪詢(在設定 RetryStrategy 一節中討論更多詳細數據)
排程工作
建立 Job
之後,必須先使用 FirebaseJobDispatcher
排程,才能執行。 排程 Job
有兩種方法:
// This will throw an exception if there was a problem scheduling the job
dispatcher.MustSchedule(myJob);
// This method will not throw an exception; an integer result value is returned
int scheduleResult = dispatcher.Schedule(myJob);
所 FirebaseJobDispatcher.Schedule
傳回的值將是下列其中一個整數值:
FirebaseJobDispatcher.ScheduleResultSuccess
Job
– 已成功排程 。FirebaseJobDispatcher.ScheduleResultUnknownError
– 發生未知的問題,導致Job
無法排程 。FirebaseJobDispatcher.ScheduleResultNoDriverAvailable
– 已使用無效IDriver
,或IDriver
以某種方式無法使用 。FirebaseJobDispatcher.ScheduleResultUnsupportedTrigger
Trigger
– 不支援 。FirebaseJobDispatcher.ScheduleResultBadService
– 服務未正確設定或無法使用。
設定作業
您可以自訂作業。 如何自訂作業的範例包括:
- 將參數傳遞至作業 – A
Job
可能需要額外的值來執行其工作,例如下載檔案。 - 設定條件約束 – 只有在符合特定條件時,才可能需要執行作業。 例如,只有在裝置充電時才會執行
Job
。 Job
指定何時應該執行 – Firebase 作業發送器可讓應用程式指定作業應該執行的時間。- 宣告失敗作業 的重試策略 – 重試策略 會針對失敗的作業提供
FirebaseJobDispatcher
相關指引Jobs
。
下列各節將進一步討論這些主題。
將參數傳遞至作業
參數會藉由建立 Bundle
與 Job.Builder.SetExtras
方法一起傳遞的 來傳遞至作業:
Bundle jobParameters = new Bundle();
jobParameters.PutInt(FibonacciCalculatorJob.FibonacciPositionKey, 25);
Job myJob = dispatcher.NewJobBuilder()
.SetService<DemoJob>("demo-job-tag")
.SetExtras(jobParameters)
.Build();
Bundle
從 IJobParameters.Extras
方法上的 OnStartJob
屬性存取 :
public override bool OnStartJob(IJobParameters jobParameters)
{
int position = jobParameters.Extras.GetInt(FibonacciPositionKey, DEFAULT_VALUE);
// rest of code omitted
}
設定條件約束
限制有助於降低裝置的成本或電池耗盡。 類別會將 Firebase.JobDispatcher.Constraint
這些條件約束定義為整數值:
Constraint.OnUnmeteredNetwork
– 只有在裝置連線到未計量的網路時,才執行作業。 這對於防止用戶產生數據費用很有用。Constraint.OnAnyNetwork
– 在裝置所連線的任何網路上執行作業。 如果與 一起Constraint.OnUnmeteredNetwork
指定,這個值會優先使用。Constraint.DeviceCharging
– 只有在裝置充電時,才執行作業。
條件約束是使用 方法設定的 Job.Builder.SetConstraint
:
Job myJob = dispatcher.NewJobBuilder()
.SetService<DemoJob>("demo-job-tag")
.SetConstraint(Constraint.DeviceCharging)
.Build();
提供 JobTrigger
操作系統的指引,說明作業何時應該啟動。 JobTrigger
有一個執行視窗,定義應該執行的排程時間Job
。 執行視窗具有 開始視窗 值和 結束視窗 值。 開始視窗是裝置在執行作業之前應該等候的秒數,而結束視窗值是執行 Job
之前等待的最大秒數。
JobTrigger
可以使用 方法建立 Firebase.Jobdispatcher.Trigger.ExecutionWindow
。 例如 Trigger.ExecutionWindow(15,60)
,表示作業應該在排程時執行 15 到 60 秒。 方法 Job.Builder.SetTrigger
用於
JobTrigger myTrigger = Trigger.ExecutionWindow(15,60);
Job myJob = dispatcher.NewJobBuilder()
.SetService<DemoJob>("demo-job-tag")
.SetTrigger(myTrigger)
.Build();
作業的預設值 JobTrigger
會以 值表示,這個值 Trigger.Now
會指定排程后儘快執行作業。
設定 RetryStrategy
Firebase.JobDispatcher.RetryStrategy
用來指定裝置在嘗試重新執行失敗作業之前,應該使用多少延遲。 RetryStrategy
有一個原則,定義將用來重新排程失敗作業的時間基底演算法,以及指定應該排程作業的視窗的執行視窗。 這個 重新排程視窗 是由兩個值所定義。 第一個值是重新排程作業之前要等候的秒數( 初始輪詢 值),而第二個值是作業必須執行前的秒數上限( 最大輪詢 值)。
下列 int 值會識別兩種類型的重試原則:
RetryStrategy.RetryPolicyExponential
– 指數 輪詢 原則會在每次失敗后以指數方式增加初始輪詢值。 作業第一次失敗時,連結庫會等候指定的_initial間隔,再重新排程作業 – 範例 30 秒。 作業第二次失敗時,連結庫會等候至少 60 秒,再嘗試執行作業。 第三次嘗試失敗之後,連結庫會等候 120 秒,依此等。 Firebase 作業發送器連結庫的預設值RetryStrategy
是由RetryStrategy.DefaultExponential
物件表示。 其初始輪詢為 30 秒,最大輪詢為 3600 秒。RetryStrategy.RetryPolicyLinear
– 此策略是 線性輪詢 ,工作應重新排程為在設定間隔執行(直到成功為止)。 線性輪詢最適合必須儘快完成的工作,或快速解決自己的問題。 Firebase 作業發送器連結庫會RetryStrategy.DefaultLinear
定義 ,其重新排程視窗至少為 30 秒,最多 3600 秒。
使用方法可以定義自定義RetryStrategy
FirebaseJobDispatcher.NewRetryStrategy
。 它採用三個參數:
int policy
– 此 原則 是上述RetryStrategy
其中一個值,RetryStrategy.RetryPolicyLinear
或RetryStrategy.RetryPolicyExponential
。int initialBackoffSeconds
– 初始 輪詢 是嘗試再次執行作業之前所需的延遲,以秒為單位。 預設值為30秒。int maximumBackoffSeconds
– 最大 輪詢 值會宣告延遲的秒數上限,然後再嘗試再次執行作業。 預設值為3600秒。
RetryStrategy retry = dispatcher.NewRetryStrategy(RetryStrategy.RetryPolicyLinear, initialBackoffSeconds, maximumBackoffSet);
// Create a Job and set the RetryStrategy via the Job.Builder
Job myJob = dispatcher.NewJobBuilder()
.SetService<DemoJob>("demo-job-tag")
.SetRetryStrategy(retry)
.Build();
取消作業
您可以使用 方法或 FirebaseJobDispatcher.Cancel(string)
方法,取消所有已排程的作業,或只取消FirebaseJobDispatcher.CancelAll()
單一作業:
int cancelResult = dispatcher.CancelAll();
// to cancel a single job:
int cancelResult = dispatcher.Cancel("unique-tag-for-job");
任一種方法都會傳回整數值:
FirebaseJobDispatcher.CancelResultSuccess
– 作業已成功取消。FirebaseJobDispatcher.CancelResultUnknownError
– 錯誤導致作業無法取消。FirebaseJobDispatcher.CancelResult.NoDriverAvailable
FirebaseJobDispatcher
– 無法取消作業,因為沒有有效的IDriver
可用作業。
摘要
本指南已討論如何使用 Firebase 作業發送器在背景中智慧地執行工作。 它討論了如何將要執行的工作封裝為 , JobService
以及如何使用 FirebaseJobDispatcher
來排程該工作、使用 指定準則 JobTrigger
以及應該 RetryStrategy
如何處理失敗。