Background Execution And WorkManager

6427501df5c44488da4cae07055897fe?s=47 Elvis Lin
December 28, 2018

Background Execution And WorkManager

Briefly introduce the background execution limitation and how to use WorkManager

6427501df5c44488da4cae07055897fe?s=128

Elvis Lin

December 28, 2018
Tweet

Transcript

  1. WorkManager
 學習⼼心得 Elvis Lin @Android Taipei
 2018-12-27

  2. 關於我 • Elvis Lin • Android 與 iOS 永遠的初學者 •

    Twitter: @elvismetaphor • Blog: https://blog.elvismetaphor.me
  3. Agenda • ⽬目前 Android 對背景執⾏行行的限制 • 處理理背景任務的⼀一般⽅方式(ex: JobScheduler) • WorkManager

  4. 背景任務的限制 • 在 Android Oreo 之後,程式在背景的執⾏行行有了了許多限制 • 所有在 Oreo 與

    Pie 執⾏行行的 apps 都會被影響 • 無法在 background 開始⼀一個 service • NO startService() • 當程式到背景時,service 會被終⽌止 • ⼤大部分 implicit broadcasts 無法在 manifest 中直接註冊監聽
  5. Service 的限制 • 在背景呼叫 startService() • IllegalStateException • 當程式從 Foreground

    移到 Background 時 • 所有的 services 只會執⾏行行⼀一⼩小段時間,然後就會結束
  6. Broadcast 的限制 • Implicit Broadcasts — 沒有特定⽬目標的 broadcasts • Static

    Receivers — 定義在 AndroidManifest.xml 中的 receivers • 在 Oreo 以後,static receivers 收不到 implicit broadcasts
  7. 解決⽅方法 • 使⽤用 JobScheduler • 使⽤用 Firebase Cloud Message,獲得短暫的背景執⾏行行時間 •

    startForegroundService() • 將任務留留到程式在前景的時候再做
  8. 使⽤用 Job • JobScheduler • Firebase JobDispatcher (當 < API

    Level 21) • AlarmManager (當 < API Level 21 ⽽而且沒有 Google Play Service)
  9. JobScheduler // Create a JobService to execute the work public

    class DownloadArtworkJobService extends JobService {
 @Override
 public boolean onStartJob(JobParameters params) {
 // Do something
 } }
 // Schedule a Job 
 JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(new JobInfo.Builder(LOAD_ARTWORK_JOB_ID, new ComponentName(this, DownloadArtworkJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .build());
  10. Firebase JobDispatcher // Create a new dispatcher using the Google

    Play driver. FirebaseJobDispatcher dispatcher = 
 new FirebaseJobDispatcher(new GooglePlayDriver(context)); Job myJob = dispatcher.newJobBuilder() .setService(MyJobService.class) // the JobService that will be called .setTag("my-unique-tag") // uniquely identifies the job .build(); dispatcher.mustSchedule(myJob);
  11. 使⽤用 FCM • 送 High Priority Message • 當收到 message

    時,app 可以有⼀一點短暫的時間在 Foreground 的狀狀態 • App 可以利利⽤用這段時間呼叫 startService() 完成⼯工作
  12. 使⽤用 startForegroundService • startForegroundService(Intent service) • 在 service 中 •

    產⽣生⼀一個 (visible) notification • 執⾏行行 startForeground(id, notification)
  13. WorkManager

  14. WorkManager • 屬於 architecture components 的⼀一部分,⽤用來來處理理 background ⼯工作 • ⽀支援條件限制與條件觸發

    (ex: 有網路路連線、充電中) • ⽀支援單次或週期性的任務 • 可以將多個 worker 串串接起來來 • 向下相容到 API 14
  15. WorkManager (續) • 沒有 Google Play Services 也可以使⽤用 • 整合多組

    API,提供⼀一致的介⾯面 • …… • BUT, ⽬目前還在 beta 階段
  16. 整合多個 APIs

  17. 基本元件 • Worker: 包含所有要在背景執⾏行行的⼯工作,開發者在 doWork() 這個 method 實作 • WorkRequest:

    內部包含 Worker 與其他必要的資訊,例例如觸 發的條件或輸入的資料 • OneTimeWorkRequest • PeriodicWorkRequest • WorkManager: 排程與控制 WorkRequest 的執⾏行行
  18. 專案的設定 • dependencies {
 // Other dependencies
 implementation “android.arch.work:work-runtime: 1.0.0-beta01”


    }
  19. 實作⼀一個 Worker Public class UploadWorker extends Worker {
 
 @NonNull


    @Override
 public Worker.Result doWork() {
 
 // do something
 return Worker.Result.success()
 }
 }
  20. Worker 回傳的狀狀態 • Worker.Result • success() • failure() • retry()

  21. 將⼯工作放入 WorkManager // Create a request
 OneTimeWorkRequest uploadRequest = 


    new OneTimeWorkRequest.Builder(UploadWorker.class)
 .build();
 
 // Schedule the request
 WorkManager workManager = WorkManager.getInstance(); workManager.enqueue(uploadRequest)
  22. 加上條件的限制 // Create a request
 OneTimeWorkRequest uploadRequest = 
 new

    OneTimeWorkRequest.Builder(UploadWorker.class)
 .setRequiresCharging(true)
 .build();
 
 // Schedule the request
 WorkManager workManager = WorkManager.getInstance(); workManager.enqueue(uploadRequest)
  23. 條件的種類 • NetworkType • Battery • Charging • DeviceIdle •

    Storage • ContentUpdate • ….
  24. 傳遞資料給 worker // Create a data
 Data.Builder builder = new

    Data.Builder();
 Data data = builder.putString(“path”, “file://some_path”);
 
 
 OneTimeWorkRequest uploadRequest = 
 new OneTimeWorkRequest.Builder(UploadWorker.class)
 .setInputData(data)
 .build();

  25. 取出資料 public Worker.Result doWork() {
 
 String path = getInputData().getString(“path”)


    
 // Do something
 }
  26. 傳遞資料給後續的 Worker public Worker.Result doWork() {
 
 // Do something


    
 Data.Builder builder = new Data.Builder();
 Data data = 
 builder.putString(“path”, “file://some_path”);
 return Worker.Result.success(data)
 }
  27. 將多個 Workers 串串連 workManager.beginWork(compressRequest) .then(uploadRequdst) .then(cleanupRequest) .enqueue();

  28. 保持⼀一次只有⼀一個特定任務在執⾏行行 workManager.beginUniqueWork( IMAGE_UPLOAD_WORK_NAME,
 ExistingWorkPolicy.REPLACE,
 compressRequest) .then(uploadRequest) .then(cleanupRequest) .enqueue();

  29. 詢問 Worker 的狀狀態 • 取得 WorkInfo
 uploadWorkInfo = workManager
 .getWorkInfosByTagLiveData(TARGET_TAG);

    • 詢問狀狀態
 uploadWorkInfo.getState() • 詢問是否已經結束
 upLoadWorkInfo.getState().isFinished();
  30. 取消 Worker 的⼯工作 • workerManbager.cancelAllWorkByTag(TARGET_TAG)

  31. 總結 • 在 Android Oreo 之後,背景執⾏行行的⼯工作有了了許多限制 • 在不同的情境下,你可以使⽤用 JobScheduler、Firebase JobDispatcher、FCM、AlarmManager

    來來完成背景的⼯工作 • WorkManager 將上述的⼤大部分功能打包,提供⼀一致的操作 介⾯面 • WorkManager ⽀支援條件執⾏行行、週期執⾏行行與多個⼯工作的串串接 等需求
  32. 補充資料 • Background Work with WorkManager
 https://codelabs.developers.google.com/codelabs/android- workmanager/

  33. 參參考資料 • Background Execution Limits
 https://developer.android.com/about/versions/oreo/background • Schedule jobs intelligently


    https://developer.android.com/topic/performance/scheduling • Guide to Background Processing
 https://developer.android.com/guide/background/ • Schedule tasks with WorkManager
 https://developer.android.com/topic/libraries/architecture/ workmanager/
  34. None