本文說明如何遷移應用程式,以便使用 WorkManager 用戶端程式庫 (而非 GCMNetworkManager 程式庫) 來執行背景作業。如果應用程式要安排背景工作,建議的方式是使用 WorkManager。此外,你也能納入 WorkManager GCM 程式庫,讓 WorkManager 在搭載 API 級別 22 以下版本的 Android 裝置上執行時,能夠使用 GCM 排定工作。
遷移至 WorkManager
如果你的應用程式目前使用 GCMNetworkManager 執行背景作業,請按照下列步驟遷移至 WorkManager。
在以下步驟中,我們假設你一開始使用的是以下 GCMNetworkManager 程式碼,該程式碼定義了你的工作並加以排程:
Kotlin
val myTask = OneoffTask.Builder() // setService() says what class does the work .setService(MyUploadService::class.java) // Don't run the task unless device is charging .setRequiresCharging(true) // Run the task between 5 & 15 minutes from now .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) // Define a unique tag for the task .setTag("test-upload") // ...finally, build the task and assign its value to myTask .build() GcmNetworkManager.getInstance(this).schedule(myTask)
Java
// In GcmNetworkManager, this call defines the task and its // runtime constraints: OneoffTask myTask = new OneoffTask.Builder() // setService() says what class does the work .setService(MyUploadService.class) // Don't run the task unless device is charging .setRequiresCharging(true) // Run the task between 5 & 15 minutes from now .setExecutionWindow( 5 * DateUtil.MINUTE_IN_SECONDS, 15 * DateUtil.MINUTE_IN_SECONDS) // Define a unique tag for the task .setTag("test-upload") // ...finally, build the task and assign its value to myTask .build(); GcmNetworkManager.getInstance(this).schedule(myTask);
在這個範例中,我們假設 MyUploadService
定義了實際上傳作業:
Kotlin
class MyUploadService : GcmTaskService() { fun onRunTask(params: TaskParams): Int { // Do some upload work return GcmNetworkManager.RESULT_SUCCESS } }
Java
class MyUploadService extends GcmTaskService { @Override public int onRunTask(TaskParams params) { // Do some upload work return GcmNetworkManager.RESULT_SUCCESS; } }
包含 WorkManager 程式庫
如要使用 WorkManager 類別,你必須將 WorkManager 程式庫新增至建構依附元件。你還必須新增 WorkManager GCM 程式庫;這樣一來,當應用程式在不支援 JobScheduler 的裝置 (即執行 API 級別 22 以下版本的裝置) 上執行時,WorkManager 就能使用 GCM 處理工作)。如需新增程式庫的完整詳細資料,請參閱開始使用 WorkManager。
修改資訊清單
實作 GCMNetworkManager 後,應按照 GcmNetworkManager
參考說明文件所述,將 GcmTaskService
執行個體加入你的應用程式資訊清單。GcmTaskService
會查看傳入的工作,並委派給工作處理常式。WorkManager 會管理對工作站的工作委派作業,因此不再需要類別來執行此工作;只要將 GcmTaskService
從資訊清單中移除即可。
定義工作站
你的 GCMNetworkManager 實作會定義 OneoffTask
或 RecurringTask
,表明需要完成的工作。按照定義工作要求所述,你必須將工作重新編寫為 Worker
。
GCMNetworkManager 程式碼範例定義了 myTask
工作。WorkManager 對應看起來會像這樣:
Kotlin
class UploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork() : Result { // Do the upload operation ... myUploadOperation() // Indicate whether the task finished successfully with the Result return Result.success() } }
Java
public class UploadWorker extends Worker { public UploadWorker( @NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @Override public Result doWork() { // Do the upload operation ... myUploadOperation() // Indicate whether the task finished successfully with the Result return Result.success() } }
GCM 工作與 Worker
之間有一些差異:
- GCM 使用
TaskParams
物件將參數傳遞至工作。WorkManager
會使用輸入資料。如要在WorkRequest
設定這項資料,你可參閱WorkManager
說明文件,瞭解如何定義工作的輸入/輸出。在這兩種情況下,你都可以傳送鍵/值組合,指定工作所需的任何可持續參數。 GcmTaskService
信號會傳回GcmNetworkManager.RESULT_SUCCESS
等旗標,指出結果為成功或失敗。WorkManagerWorker
使用ListenableWorker.Result.success()
等ListenableWorker.Result
方法指出其結果,並傳回該方法的傳回值。- 如先前所述,你不必在定義
Worker
時設定限制條件或標記;而是在下一個步驟建立WorkRequest
時設定。
安排工作要求
定義 Worker
會指定你需要的「結果」。如要指定工作的完成時間,你必須定義 WorkRequest
:
- 建立
OneTimeWorkRequest
或PeriodicWorkRequest
,並設定任何想要的限制條件來指定工作執行時間,以及任何有助辨別工作的標記。 - 將要求傳遞至
WorkManager.enqueue()
,以將工作排入佇列等待執行。
例如,上一節說明如何將 OneoffTask
轉換為對等的 Worker
。不過,這個 Worker
並不包含 OneoffTask
物件的執行限制和標記。因此,我們是在建立 WorkRequest
時設下限制和工作 ID。我們也會指定,除非有網路連線,否則工作不得執行。根據預設,GCM 管理員需要網路連線,因為 GCMNetworkManager 預設為需要網路連線,但除非你特別新增限制,否則 WorkManager 不需要網路連線。定義 WorkRequest
後,我們會使用 WorkManager 將其排入佇列。
Kotlin
val uploadConstraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true).build() val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>() .setConstraints(uploadConstraints) .build() WorkManager.getInstance().enqueue(uploadTask)
Java
Constraints uploadConstraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true) .build(); OneTimeWorkRequest uploadTask = new OneTimeWorkRequest.Builder(UploadWorker.class) .setConstraints(uploadConstraints) .build(); WorkManager.getInstance().enqueue(uploadTask);
API 對應
本節說明部分 GCMNetworkManager 功能與限制如何對應至 WorkManager 對等項目。
限制對應
GCMNetworkManager 可讓你設定工作執行時間的幾個限制。在多數情況下,都會有明確的 WorkManager 限制對等項目。本節會列出這些對等項目。
在工作的 Builder 物件中呼叫適當的方法,以設定 GCMNetworkManager 工作的限制;舉例來說,你可以呼叫 Task.Builder.setRequiredNetwork()
來設定網路需求。
在 WorkManager 中,建立 Constraints.Builder
物件並呼叫該物件的方法,藉此設定限制 (例如 Constraints.Builder.setRequiredNetworkType())
),然後使用 Builder 建立限制物件,並將該物件附加至工作要求。詳情請參閱定義工作要求。
GCMNetworkManager 限制 | WorkManager 對應 | 附註 |
---|---|---|
setPersisted() |
(非必要) | 每部裝置重新啟動後都會保留所有 WorkManager 工作 |
setRequiredNetwork() |
setRequiredNetworkType() |
根據預設,GCMNetworkManager 需要網路存取權。根據預設,WorkManager 不需要網路存取權。如果你的工作需要存取網路,你必須使用 setRequiredNetworkType(CONNECTED) ,或設定更具體的網路類型。 |
setRequiresCharging() |
其他對應
除了限制外,你還可以將其他設定套用到 GCMNetworkManager 工作。本節列出將這些設定套用至 WorkManager 工作的對應方法。
標記
所有 GCMNetworkManager 工作都必須包含標記字串,而你必須透過呼叫 Builder 的 setTag()
方法來設定這些字串。WorkManager 工作是由 WorkManager 自動產生的不重複 ID 所代表;你可以呼叫 WorkRequest.getId()
來取得這個 ID。此外,工作要求也「可以」具有一或多個標記。如要為 WorkManager 工作設定標記,請先呼叫 WorkRequest.Builder.addTag()
方法,再使用 Builder 建立 WorkRequest
。
在 GCMNetworkManager 中,你可以呼叫 setUpdateCurrent()
來指定工作是否應以相同的標記取代任何現有的工作。
對應的 WorkManager 方法是透過呼叫 enqueueUniqueWork()
或 enqueueUniquePeriodicWork()
將工作排入佇列。如果使用上述方法,你可以為工作指定專屬名稱,並指定 WorkManager 如何處理已使用該名稱的待處理工作。詳情請參閱處理不重複的工作。
工作參數
你可以呼叫 Task.Builder.setExtras()
並傳遞包含參數的 Bundle
,以將參數傳遞至 GCMNetworkManager 工作。WorkManager 可讓你將 Data
物件傳遞至 WorkManager 工作,其中包含參數做為鍵/值組合。詳情請參閱指派輸入資料一文。