Android Kotlin 基礎知識 09.2:WorkManager

這個程式碼研究室是 Android Kotlin 基礎知識課程的一部分。如果您按部就班完成程式碼研究室,就能充分體驗到本課程的價值。所有課程程式碼研究室都列在 Android Kotlin 基礎知識程式碼研究室到達網頁。

簡介

大多數實際應用程式都需要執行長時間執行的背景工作。舉例來說,應用程式可能會將檔案上傳至伺服器、從伺服器同步處理資料並儲存至 Room 資料庫、將記錄檔傳送至伺服器,或對資料執行耗用資源的作業。這類作業應在背景執行,而非 UI 執行緒 (主執行緒)。背景工作會耗用裝置的有限資源,例如 RAM 和電池。如果處理不當,可能會導致使用者體驗不佳。

在本程式碼研究室中,您將瞭解如何使用 WorkManager 以經過最佳化的方式有效率地排定背景工作。如要進一步瞭解 Android 中其他可用的背景處理解決方案,請參閱「背景處理指南」。

必備知識

  • 如何使用 ViewModel、LiveData 和 Room Android 架構元件。
  • 如何對 LiveData 類別執行轉換。
  • 如何建立及啟動協同程式。
  • 如何在資料繫結中使用繫結轉接器。
  • 如何使用存放區模式載入快取資料。

課程內容

  • 如何建立 Worker,代表一個工作單元。
  • 如何建立 WorkRequest,要求執行工作。
  • 如何將限制新增至 WorkRequest,定義 worker 的執行方式和時間。
  • 如何使用 WorkManager 安排背景工作時程。

學習內容

  • 建立工作者,執行背景工作,從網路預先擷取 DevBytes 影片播放清單。
  • 排定定期執行 worker。
  • 在 WorkRequest 中新增限制條件。
  • 排定每日執行一次的週期性 WorkRequest。

在本程式碼研究室中,您將使用先前程式碼研究室中開發的 DevBytes 應用程式。(如果沒有這個應用程式,可以下載本課程的範例程式碼)。

DevBytes 應用程式會顯示 DevBytes 影片清單,內容都是由 Google Android 開發人員關係團隊製作的教學課程短片。這些影片介紹了 Android 開發人員功能和最佳做法。

每天預先擷取影片,提升應用程式的使用者體驗。確保使用者開啟應用程式時,能立即取得最新內容。

在這項工作中,您將下載並檢查範例程式碼。

步驟 1:下載並執行入門應用程式

您可以繼續使用先前程式碼研究室中建構的 DevBytes 應用程式 (如有)。您也可以下載入門應用程式。

在這項工作中,您將下載並執行範例應用程式,然後檢查範例程式碼。

  1. 如果您還沒有 DevBytes 應用程式,請從 GitHub 的 DevBytesRepository 專案下載本程式碼研究室的 DevBytes 範例程式碼。
  2. 解壓縮程式碼,並在 Android Studio 中開啟專案。
  3. 將測試裝置或模擬器連上網際網路 (如果尚未連線)。建構並執行應用程式。應用程式會從網路擷取 DevByte 影片清單,並顯示這些影片。
  4. 在應用程式中輕觸任一影片,即可在 YouTube 應用程式中開啟該影片。

步驟 2:探索程式碼

範例應用程式包含許多在先前程式碼研究室中介紹過的程式碼。本程式碼研究室的起始程式碼包含網路、使用者介面、離線快取和存放區模組。您可以使用 WorkManager 專注於安排背景工作。

  1. 在 Android Studio 中展開所有套件。
  2. 探索 database 套件。這個套件包含資料庫實體和本機資料庫,後者是使用 Room 實作。
  3. 探索 repository 套件。這個套件包含 VideosRepository 類別,可從應用程式的其他部分提取資料層。
  4. 請自行探索其餘的範例程式碼,並參考先前的程式碼研究室。

WorkManager 是 Android 架構元件之一,也是 Android Jetpack 的一部分。WorkManager 適用於可延後且必須執行的背景工作:

  • 可延後表示工作不需要立即執行。舉例來說,將分析資料傳送至伺服器,或在背景同步處理資料庫,都是可以延後的工作。
  • 保證執行是指即使應用程式結束或裝置重新啟動,工作仍會執行。

WorkManager 執行背景工作時,會處理相容性問題,並採用電池和系統健康狀態最佳做法。WorkManager 可回溯相容至 API 級別 14。WorkManager 會根據裝置 API 級別,選擇適當的方式排定背景工作。這項功能可能會使用 JobScheduler (適用於 API 23 以上版本),或 AlarmManager 和 BroadcastReceiver 的組合。

您也可以使用 WorkManager 設定背景工作執行的條件。舉例來說,您可能希望只有在電池狀態、網路狀態或充電狀態符合特定條件時,才執行工作。您將在本程式碼研究室稍後瞭解如何設定限制。

在本程式碼研究室中,您將排定工作,每天從網路預先擷取一次 DevBytes 影片播放清單。如要排定這項工作,請使用 WorkManager 程式庫。

  1. 開啟 build.gradle (Module:app) 檔案,然後將 WorkManager 依附元件新增至專案。

    如果您使用最新版程式庫,解決方案應用程式應會如預期編譯。如果沒有,請嘗試解決問題,或還原為下方顯示的程式庫版本。
// WorkManager dependency
def work_version = "1.0.1"
implementation "android.arch.work:work-runtime-ktx:$work_version"
  1. 同步處理專案,確保沒有編譯錯誤。

將程式碼新增至專案前,請先熟悉 WorkManager 程式庫中的下列類別:

  • Worker
    您可以在這個類別中定義要在背景執行的實際工作 (工作)。您會擴充這個類別並覆寫 doWork() 方法。doWork() 方法是用來放置要在背景執行的程式碼,例如與伺服器同步處理資料或處理圖片。在這項工作中,您會實作 Worker。
  • WorkRequest
    這個類別代表在背景執行工作站的要求。使用 WorkRequest 設定執行工作者工作的方式和時間,例如裝置已接上電源或連上 Wi-Fi。Constraints 可協助您完成這項設定。您會在後續工作中實作 WorkRequest。
  • WorkManager
    這個類別會排定及執行 WorkRequest。WorkManager 會以在系統資源上分散負載的方式排定工作要求,同時遵循您指定的限制條件。您會在後續工作中實作 WorkManager。

步驟 1:建立工作人員

在這項工作中,您要新增 Worker,在背景中預先擷取 DevBytes 影片播放清單。

  1. 在 devbyteviewer 套件中,建立名為 work 的新套件。
  2. 在 work 套件中,建立名為 RefreshDataWorker 的新 Kotlin 類別。
  3. 從 CoroutineWorker 類別擴充 RefreshDataWorker 類別。傳入 context 和 WorkerParameters 做為建構函式參數。
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {
}
  1. 如要解決抽象類別錯誤,請覆寫 RefreshDataWorker 類別中的 doWork() 方法。
override suspend fun doWork(): Result {
  return Result.success()
}

暫停函式是指可以暫停,稍後再繼續執行的函式。暫停函式可以執行長時間作業,並等待作業完成,而不會封鎖主執行緒。

步驟 2:實作 doWork()

系統會在背景執行緒中呼叫 Worker 類別內的 doWork() 方法。這個方法會同步執行工作,並應傳回 ListenableWorker.Result 物件。Android 系統最多會給予 Worker 10 分鐘的時間完成執行作業,並傳回 ListenableWorker.Result 物件。時間到期後,系統會強制停止 Worker。

如要建立 ListenableWorker.Result 物件,請呼叫下列其中一個靜態方法,指出背景工作的完成狀態:

在這項工作中,您會實作 doWork() 方法,從網路擷取 DevBytes 影片播放清單。您可以重複使用 VideosRepository 類別中的現有方法,從網路擷取資料。

  1. 在 RefreshDataWorker 類別的 doWork() 內,建立並例項化 VideosDatabase 物件和 VideosRepository 物件。
override suspend fun doWork(): Result {
   val database = getDatabase(applicationContext)
   val repository = VideosRepository(database)

   return Result.success()
}
  1. 在 RefreshDataWorker 類別的 doWork() 內,於 return 陳述式上方,在 try 區塊內呼叫 refreshVideos() 方法。新增記錄,追蹤工作站的執行時間。
try {
   repository.refreshVideos( )
   Timber.d("Work request for sync is run")
   } catch (e: HttpException) {
   return Result.retry()
}

如要解決「未解析的參照」錯誤,請匯入 retrofit2.HttpException。

  1. 以下是完整的 RefreshDataWorker 類別,供您參考:
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {

   override suspend fun doWork(): Result {
       val database = getDatabase(applicationContext)
       val repository = VideosRepository(database)
       try {
           repository.refreshVideos()
       } catch (e: HttpException) {
           return Result.retry()
       }
       return Result.success()
   }
}

Worker 定義了作業單位,而 WorkRequest 則定義了作業的執行方式和時間。WorkRequest 類別有兩種具體實作方式:

  • OneTimeWorkRequest 類別適用於一次性工作。(一次性工作只會執行一次)。
  • PeriodicWorkRequest 類別適用於週期性工作,即會間隔一段時間重複執行的工作。

工作可能是一次性或週期性,請據此選擇課程。如要進一步瞭解如何排定週期性工作,請參閱週期性工作說明文件。

在這項工作中,您將定義並排定 WorkRequest,以執行在上一個工作中建立的背景工作。

步驟 1:設定週期性工作

在 Android 應用程式中,Application 類別是包含所有其他元件 (例如活動和服務) 的基礎類別。建立應用程式或套件的程序時,系統會先例項化 Application 類別 (或 Application 的任何子類別),再例項化任何其他類別。

在本範例應用程式中,DevByteApplication 類別是 Application 類別的子類別。DevByteApplication 類別是排定 WorkManager 的好地方。

  1. 在 DevByteApplication 類別中,建立名為 setupRecurringWork() 的方法,設定週期性背景工作。
/**
* Setup WorkManager background job to 'fetch' new network data daily.
*/
private fun setupRecurringWork() {
}
  1. 在 setupRecurringWork() 方法中,使用 PeriodicWorkRequestBuilder() 方法建立並初始化定期工作要求,以便每天執行一次。傳入您在先前工作中建立的 RefreshDataWorker 類別。傳入重複間隔 1,時間單位為 TimeUnit.DAYS。
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .build()

如要解決這項錯誤,請匯入 java.util.concurrent.TimeUnit。

步驟 2:使用 WorkManager 安排 WorkRequest

定義 WorkRequest 後,您可以使用 enqueueUniquePeriodicWork() 方法,透過 WorkManager 安排時間。這個方法可讓您將具有專屬名稱的 PeriodicWorkRequest 新增至佇列,一次只能有一個特定名稱的 PeriodicWorkRequest 處於啟用狀態。

舉例來說,您可能只希望一個同步作業處於啟用狀態。如果有一個同步作業待處理,您可以選擇讓該作業執行,或使用 ExistingPeriodicWorkPolicy 將其替換為新工作。

如要進一步瞭解如何排定 WorkRequest,請參閱 WorkManager 說明文件。

  1. 在 RefreshDataWorker 類別中,於類別開頭新增伴生物件。定義工作名稱,以便唯一識別這個工作人員。
companion object {
   const val WORK_NAME = "com.example.android.devbyteviewer.work.RefreshDataWorker"
}
  1. 在 DevByteApplication 類別中,於 setupRecurringWork() 方法結尾使用 enqueueUniquePeriodicWork() 方法排定工作。傳遞 KEEP 列舉,做為 ExistingPeriodicWorkPolicy。傳入 repeatingRequest 做為 PeriodicWorkRequest 參數。
WorkManager.getInstance().enqueueUniquePeriodicWork(
       RefreshDataWorker.WORK_NAME,
       ExistingPeriodicWorkPolicy.KEEP,
       repeatingRequest)

如果存在同名的待處理 (未完成) 工作,ExistingPeriodicWorkPolicy.KEEP 參數會讓 WorkManager 保留先前的週期性工作,並捨棄新的工作要求。

  1. 在 DevByteApplication 類別的開頭,建立 CoroutineScope 物件。傳入 Dispatchers.Default 做為建構函式參數。
private val applicationScope = CoroutineScope(Dispatchers.Default)
  1. 在 DevByteApplication 類別中,新增名為 delayedInit() 的方法來啟動協同程式。
private fun delayedInit() {
   applicationScope.launch {
   }
}
  1. 在 delayedInit() 方法中呼叫 setupRecurringWork()。
  2. 將 Timber 初始化作業從 onCreate() 方法移至 delayedInit() 方法。
private fun delayedInit() {
   applicationScope.launch {
       Timber.plant(Timber.DebugTree())
       setupRecurringWork()
   }
}
  1. 在 DevByteApplication 類別中,於 onCreate() 方法結尾新增 delayedInit() 方法的呼叫。
override fun onCreate() {
   super.onCreate()
   delayedInit()
}
  1. 開啟 Android Studio 視窗底部的「Logcat」窗格。篩選「RefreshDataWorker」。
  2. 執行應用程式。WorkManager 會立即排定週期性工作。

    在「Logcat」窗格中,請注意顯示工作要求已排定時間,然後順利執行的記錄陳述式。
D/RefreshDataWorker: Work request for sync is run
I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]

系統會從 WorkManager 媒體庫顯示 WM-WorkerWrapper 記錄,因此您無法變更這則記錄訊息。

步驟 3:(選用) 安排 WorkRequest 的最短間隔

在這個步驟中,您要將時間間隔從 1 天縮短為 15 分鐘。這麼做是為了查看定期工作要求實際運作時的記錄。

  1. 在 DevByteApplication 類別的 setupRecurringWork() 方法中,註解掉目前的 repeatingRequest 定義。新增週期性工作要求,重複間隔為 15 分鐘。
// val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
//        .build()
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(15, TimeUnit.MINUTES)
       .build()
  1. 在 Android Studio 中開啟「Logcat」窗格,然後篩選 RefreshDataWorker。如要清除先前的記錄,請按一下「Clear logcat」圖示 。
  2. 執行應用程式,WorkManager 會立即排定週期性工作。在「Logcat」窗格中,請注意記錄檔,工作要求每 15 分鐘執行一次。請等待 15 分鐘,查看另一組工作要求記錄。你可以讓應用程式保持執行狀態或關閉應用程式,工作管理員仍會繼續執行。

    請注意,間隔有時會少於 15 分鐘,有時則會超過 15 分鐘。(實際時間取決於作業系統的電池最佳化設定)。
12:44:40 D/RefreshDataWorker: Work request for sync is run
12:44:40 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
12:59:24 D/RefreshDataWorker: Work request for sync is run
12:59:24 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
13:15:03 D/RefreshDataWorker: Work request for sync is run
13:15:03 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
13:29:22 D/RefreshDataWorker: Work request for sync is run
13:29:22 I/WM-WorkerWrapper: Worker result SUCCESS for Work 
13:44:26 D/RefreshDataWorker: Work request for sync is run
13:44:26 I/WM-WorkerWrapper: Worker result SUCCESS for Work
 

恭喜!您已建立工作人員,並使用 WorkManager 排定工作要求。但問題是,您並未指定任何限制。WorkManager 每天會排定一次工作,即使裝置電力不足、處於休眠狀態或沒有網路連線也一樣。這會影響裝置電池和效能,導致使用者體驗不佳。

在下一個工作中,您會新增限制來解決這個問題。

在先前的工作中,您使用 WorkManager 排定工作要求。在這項工作中,您要新增執行工作的條件。

定義 WorkRequest 時,您可以指定 Worker 的執行時間限制。舉例來說,您可能只想在裝置閒置時執行工作,或只想在裝置接上電源並連上 Wi-Fi 時執行工作。您也可以指定重試工作的退避政策。支援的限制是 Constraints.Builder 中的設定方法。詳情請參閱「定義工作要求」。

步驟 1:新增 Constraints 物件並設定一項限制

在這個步驟中,您會建立 Constraints 物件,並在該物件上設定一項限制,也就是網路類型限制。(如果只有一個限制,就更容易注意到記錄。您會在後續步驟中新增其他限制條件)。

  1. 在 DevByteApplication 類別中,於 setupRecurringWork() 開頭定義 Constraints 類型的 val。請使用 Constraints.Builder() 方法。
val constraints = Constraints.Builder()

如要解決這項錯誤,請匯入 androidx.work.Constraints。

  1. 使用 setRequiredNetworkType() 方法將網路類型限制新增至 constraints 物件。使用 UNMETERED 列舉,讓工作要求只在裝置連上非計量付費網路時執行。
.setRequiredNetworkType(NetworkType.UNMETERED)
  1. 使用 build() 方法從建構工具產生限制。
val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .build()

現在,您需要將新建立的 Constraints 物件設為工作要求。

  1. 在 DevByteApplication 類別的 setupRecurringWork() 方法中,將 Constraints 物件設為週期性工作要求 repeatingRequest。如要設定限制,請在 build() 方法呼叫上方新增 setConstraints() 方法。
       val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(15, TimeUnit.MINUTES)
               .setConstraints(constraints)
               .build()

步驟 2:執行應用程式並注意記錄

在這個步驟中,您會執行應用程式,並注意受限的工作要求會以間隔在背景執行。

  1. 從裝置或模擬器解除安裝應用程式,即可取消先前排定的工作。
  2. 在 Android Studio 中開啟「Logcat」窗格。在「Logcat」窗格中,按一下左側的「Clear logcat」圖示 ,清除先前的記錄。篩選「work」。
  3. 在裝置或模擬器中關閉 Wi-Fi,即可查看限制的運作方式。目前的程式碼只會設定一項限制,指出要求只能在非按流量計費的網路上執行。由於 Wi-Fi 已關閉,裝置不會連線至任何網路 (無論是否為計量付費網路)。因此無法滿足這項限制。
  4. 執行應用程式,並注意「Logcat」窗格。WorkManager 會立即安排背景工作。由於未滿足網路限制,因此工作不會執行。
11:31:44 D/DevByteApplication: Periodic Work request for sync is scheduled
  1. 開啟裝置或模擬器中的 Wi-Fi,並觀察「Logcat」窗格。現在,只要符合網路限制,排定的背景工作就會大約每 15 分鐘執行一次。
11:31:44 D/DevByteApplication: Periodic Work request for sync is scheduled
11:31:47 D/RefreshDataWorker: Work request for sync is run
11:31:47 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]
11:46:45 D/RefreshDataWorker: Work request for sync is run
11:46:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:03:05 D/RefreshDataWorker: Work request for sync is run
12:03:05 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:16:45 D/RefreshDataWorker: Work request for sync is run
12:16:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:31:45 D/RefreshDataWorker: Work request for sync is run
12:31:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
12:47:05 D/RefreshDataWorker: Work request for sync is run
12:47:05 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 
13:01:45 D/RefreshDataWorker: Work request for sync is run
13:01:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]

步驟 3:新增更多限制

在這個步驟中,您要將下列限制新增至 PeriodicWorkRequest:

  • 電量充足。
  • 裝置正在充電。
  • 裝置閒置;僅適用於 API 級別 23 (Android M) 以上版本。

在 DevByteApplication 類別中實作以下內容。

  1. 在 DevByteApplication 類別的 setupRecurringWork() 方法中,指出工作要求只應在電量充足時執行。在 build() 方法呼叫之前新增限制條件,並使用 setRequiresBatteryNotLow() 方法。
.setRequiresBatteryNotLow(true)
  1. 更新工作要求,讓系統只在裝置充電時執行工作。在 build() 方法呼叫之前新增限制條件,並使用 setRequiresCharging() 方法。
.setRequiresCharging(true)
  1. 更新工作要求,讓工作只在裝置閒置時執行。在 build() 方法呼叫之前新增限制條件,並使用 setRequiresDeviceIdle() 方法。這項限制條件只會在使用者未主動使用裝置時執行工作要求。這項功能僅適用於 Android 6.0 (Marshmallow) 以上版本,因此請為 SDK 版本 M 以上版本新增條件。
.apply {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       setRequiresDeviceIdle(true)
   }
}

以下是 constraints 物件的完整定義。

val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresBatteryNotLow(true)
       .setRequiresCharging(true)
       .apply {
           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
               setRequiresDeviceIdle(true)
           }
       }
       .build()
  1. 在 setupRecurringWork() 方法中,將要求間隔改回每天一次。
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .setConstraints(constraints)
       .build()

以下是 setupRecurringWork() 方法的完整實作內容,其中包含記錄,方便您追蹤定期工作要求的排程時間。

private fun setupRecurringWork() {

       val constraints = Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .setRequiresBatteryNotLow(true)
               .setRequiresCharging(true)
               .apply {
                   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                       setRequiresDeviceIdle(true)
                   }
               }
               .build()
       val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
               .setConstraints(constraints)
               .build()
       
       Timber.d("Periodic Work request for sync is scheduled")
       WorkManager.getInstance().enqueueUniquePeriodicWork(
               RefreshDataWorker.WORK_NAME,
               ExistingPeriodicWorkPolicy.KEEP,
               repeatingRequest)
   }
  1. 如要移除先前排定的工作要求,請從裝置或模擬器解除安裝 DevBytes 應用程式。
  2. 執行應用程式,WorkManager 會立即安排工作要求。符合所有限制後,工作要求就會每天執行一次。
  3. 只要應用程式已安裝,即使未執行,這項工作要求也會在背景執行。因此,請從手機解除安裝該應用程式。

太棒了!您已為 DevBytes 應用程式中每日預先擷取的影片,實作並排定省電的工作要求。WorkManager 會排定及執行工作,並最佳化系統資源。使用者和電池都會非常滿意。

Android Studio 專案:DevBytesWorkManager。

  • WorkManager API 可讓您輕鬆排定工作時間,以可靠的方式執行可延後的非同步工作。
  • 大多數實際應用程式都需要執行長時間執行的背景工作。如要以經過最佳化的方式有效率地排定背景工作,請使用 WorkManager。
  • WorkManager 程式庫中的主要類別為 Worker、WorkRequest 和 WorkManager。
  • Worker 類別代表一個工作單元。如要實作背景工作,請擴充 Worker 類別並覆寫 doWork() 方法。
  • WorkRequest 類別代表執行工作單元的要求。WorkRequest 是指定在 WorkManager 中排定工作參數的基礎類別。
  • WorkRequest 類別有兩種具體實作方式:OneTimeWorkRequest 用於一次性工作,PeriodicWorkRequest 用於週期性工作要求。
  • 定義 WorkRequest 時,您可以指定 Constraints,指出 Worker 的執行時間。限制包括裝置是否已接上電源、是否處於閒置狀態,以及是否已連上 Wi-Fi。
  • 如要為 WorkRequest 新增限制,請使用Constraints.Builder 說明文件中列出的設定方法。舉例來說,如要指出裝置電量不足時不應執行 WorkRequest,請使用 setRequiresBatteryNotLow() set 方法。
  • 定義 WorkRequest 後,請將工作交給 Android 系統。如要執行這項操作,請使用其中一個 WorkManager enqueue 方法排定工作。
  • Worker 的確切執行時間取決於 WorkRequest 中使用的限制條件,以及系統最佳化作業。WorkManager 的設計宗旨,就是要提供受此限制的最佳行為。

Udacity 課程:

Android 開發人員說明文件:

其他:

本節列出的作業可由課程講師指派給學習本程式碼研究室的學員。講師可自由採取以下行動:

  • 視需要指派作業。
  • 告知學員如何繳交作業。
  • 為作業評分。

講師可以視需求使用全部或部分建議內容,也可以自由指派任何其他合適的作業。

如果您是自行學習本程式碼研究室,不妨利用這些作業驗收學習成果。

第 1 題

下列何者是 WorkRequest 類別的具體實作?

▢ OneTimeWorkPeriodicRequest

▢ OneTimeWorkRequest 和 PeriodicWorkRequest

▢ OneTimeWorkRequest 和 RecurringWorkRequest

▢ OneTimeOffWorkRequest 和 RecurringWorkRequest

第 2 題

WorkManager 會使用下列哪些類別來排程 API 23 以上版本的背景工作?

▢ 僅限 JobScheduler

▢ BroadcastReceiver 和 AlarmManager

▢ AlarmManager 和 JobScheduler

▢ Scheduler 和 BroadcastReceiver

第 3 題

哪一個 API 可以用來將限制條件新增至 WorkRequest?

▢ setConstraints()

▢ addConstraints()

▢ setConstraint()

▢ addConstraintsToWorkRequest()

開始下一個課程:10.1 樣式與主題

如要查看本課程其他程式碼研究室的連結,請參閱 Android Kotlin 基礎知識程式碼研究室登陸頁面。