Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Background Execution And WorkManager

Elvis Lin
December 28, 2018

Background Execution And WorkManager

Briefly introduce the background execution limitation and how to use WorkManager

Elvis Lin

December 28, 2018
Tweet

More Decks by Elvis Lin

Other Decks in Programming

Transcript

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

    Twitter: @elvismetaphor • Blog: https://blog.elvismetaphor.me
  2. 背景任務的限制 • 在 Android Oreo 之後,程式在背景的執⾏行行有了了許多限制 • 所有在 Oreo 與

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

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

    Receivers — 定義在 AndroidManifest.xml 中的 receivers • 在 Oreo 以後,static receivers 收不到 implicit broadcasts
  5. 使⽤用 Job • JobScheduler • Firebase JobDispatcher (當 < API

    Level 21) • AlarmManager (當 < API Level 21 ⽽而且沒有 Google Play Service)
  6. 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());
  7. 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);
  8. 使⽤用 FCM • 送 High Priority Message • 當收到 message

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

    產⽣生⼀一個 (visible) notification • 執⾏行行 startForeground(id, notification)
  10. WorkManager • 屬於 architecture components 的⼀一部分,⽤用來來處理理 background ⼯工作 • ⽀支援條件限制與條件觸發

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

    API,提供⼀一致的介⾯面 • …… • BUT, ⽬目前還在 beta 階段
  12. 基本元件 • Worker: 包含所有要在背景執⾏行行的⼯工作,開發者在 doWork() 這個 method 實作 • WorkRequest:

    內部包含 Worker 與其他必要的資訊,例例如觸 發的條件或輸入的資料 • OneTimeWorkRequest • PeriodicWorkRequest • WorkManager: 排程與控制 WorkRequest 的執⾏行行
  13. 實作⼀一個 Worker Public class UploadWorker extends Worker {
 
 @NonNull


    @Override
 public Worker.Result doWork() {
 
 // do something
 return Worker.Result.success()
 }
 }
  14. 將⼯工作放入 WorkManager // Create a request
 OneTimeWorkRequest uploadRequest = 


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

    OneTimeWorkRequest.Builder(UploadWorker.class)
 .setRequiresCharging(true)
 .build();
 
 // Schedule the request
 WorkManager workManager = WorkManager.getInstance(); workManager.enqueue(uploadRequest)
  16. 傳遞資料給 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();

  17. 傳遞資料給後續的 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)
 }
  18. 詢問 Worker 的狀狀態 • 取得 WorkInfo
 uploadWorkInfo = workManager
 .getWorkInfosByTagLiveData(TARGET_TAG);

    • 詢問狀狀態
 uploadWorkInfo.getState() • 詢問是否已經結束
 upLoadWorkInfo.getState().isFinished();
  19. 總結 • 在 Android Oreo 之後,背景執⾏行行的⼯工作有了了許多限制 • 在不同的情境下,你可以使⽤用 JobScheduler、Firebase JobDispatcher、FCM、AlarmManager

    來來完成背景的⼯工作 • WorkManager 將上述的⼤大部分功能打包,提供⼀一致的操作 介⾯面 • WorkManager ⽀支援條件執⾏行行、週期執⾏行行與多個⼯工作的串串接 等需求
  20. 參參考資料 • 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/