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

Introduction to Android WorkManager

Introduction to Android WorkManager

A presentation about Android WorkManager shown on GDG Szczecin event - Android Meetup #1.

Link to GitHub repository:
https://github.com/bartoszostrowski/WorkManagerExample

Bartosz Ostrowski

February 11, 2020
Tweet

Other Decks in Programming

Transcript

  1. Architecture Components • DataBinding • Room • WorkManager • LiveData

    • Navigation • Paging • ViewModel • Lifecycle
  2. What is it for? WorkManager is intended for tasks that

    are deferrable—that is, not required to run immediately — and required to run reliably even if the app exits or the device restarts.
  3. Key features • Compatibility up to Android 4.0 • Work

    constraints: network, battery level, ... • Scheduling single of recurring tasks • Chaining tasks • Monitoring and managing scheduled tasks
  4. Sample scenarios • Google Drive app - one-time worker for

    sending scan (waits for WiFi connection to sync) • Language learning apps (e.g. Duolingo or Memrise) - for daily notifications about new words to learn (recurring worker) • Instagram - chained worker for more complex tasks: take photo, apply filter, upload to server, share on Facebook and/or Twitter
  5. Compatibility Backward compatibility up to API 14 • Devices running

    API 14-22 : AlarmManager + BroadcastReceiver • Devices running API 23+: JobScheduler
  6. dependencies { def work_version = "2.3.1" // (Java only) implementation

    "androidx.work:work-runtime:$work_version" // Kotlin + coroutines implementation "androidx.work:work-runtime-ktx:$work_version" // RxJava2 support implementation "androidx.work:work-rxjava2:$work_version" // GCMNetworkManager support implementation "androidx.work:work-gcm:$work_version" // Test helpers androidTestImplementation "androidx.work:work-testing:$work_version" }
  7. class SampleWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) { override

    fun doWork(): Result { // Do sth! return Result.success() } } val request: OneTimeWorkRequest = OneTimeWorkRequest.Builder(SampleWorker::class.java) .build() WorkManager.getInstance(applicationContext).enqueue(request)
  8. Supported constraints • Network connection (by type: connected, metered, unmetered,

    not required, not roaming) • Battery not low • Charging • Storage not low • Device idle
  9. What if the job fails? Work may finish with the

    following results: • SUCCESS • RETRY • FAILURE WorkManager has defined back-off policies: • LINEAR • EXPONENTIAL
  10. // Request builder val retryingRequest = OneTimeWorkRequest.Builder(RetryingWorker::class.java) .setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.MINUTES)

    .build() WorkManager.getInstance(applicationContext).enqueue(retryingRequest) // Worker override fun doWork(): Result { if (runAttemptCount > 3) { return Result.failure() } return Result.retry() }
  11. Repeating task • Dedicated for regular, cyclic tasks, e.g. database

    backup • Can be scheduled with minimal 15 minute frequency • Cannot be used as a timer. It is not fully deterministic in timely manner.
  12. val request = PeriodicWorkRequest .Builder(RecurringWorker::class.java, 4, TimeUnit.HOURS) .build() WorkManager.getInstance(applicationContext) .enqueueUniquePeriodicWork("recurring",

    ExistingPeriodicWorkPolicy.REPLACE, request) WorkManager.getInstance(applicationContext) .enqueueUniquePeriodicWork("recurring", ExistingPeriodicWorkPolicy.KEEP, request)
  13. Old vs. new approach... … for cyclic notifications • Boot

    complete broadcast receiver • App update broadcast receiver • Manifest update: permissions, receivers • Maintaining AlarmManager for notifications • Worker + request builder Old New
  14. Chaining work • Can be scheduled to run in parallel

    • Can be schedule to run sequentially, feeding latter worker with a result of the prior task.
  15. Proprietary + Confidential Source: Lorem ipsum dolor sit amet, consectetur

    adipiscing elit. Duis non erat sem Chaining work
  16. class UploadWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) { override

    fun doWork(): Result { val input = inputData.getString("value") val time = System.currentTimeMillis() // Fake job for 15 seconds Thread.sleep(15000) val output = Data.Builder() .putString("value", "$input + UPLOAD") .build() Log.d(TAG, "doWork() : Work is done. Took = " + (System.currentTimeMillis() - time) + " ms. Output = " + output.getString("value")) return Result.success(output) }
  17. class CompressWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) { override

    fun doWork(): Result { val input = inputData.getString("value") val time = System.currentTimeMillis() // Fake job for 15 seconds Thread.sleep(15000) val output = Data.Builder() .putString("value", "$input + COMPRESS") .build() Log.d(TAG, "doWork() : Work is done. Took = " + (System.currentTimeMillis() - time) + " ms. Output = " + output.getString("value")) return Result.success(output) }
  18. val output = Data.Builder() .putString("keyA", "value1") .putInt("keyB", 1) .putString("keyC", "valueC")

    .build() val output = Data.Builder() .putString("keyA", "value2") .putInt("keyB", 2) .putString("keyD", "valueD") .build() // Result of Worker3 -> {keyA = value1, keyB = 1, keyC = valueC, keyD = valueD} // or // Result of Worker3 -> {keyA = value2, keyB = 2, keyC = valueC, keyD = valueD}
  19. val output = Data.Builder() .putString("keyA", "value1") .putInt("keyB", 1) .putString("keyC", "valueC")

    .build() val output = Data.Builder() .putString("keyA", "value2") .putInt("keyB", 2) .putString("keyD", "valueD") .build() // keyA = [value1, value2] // keyB = [1, 2] // keyC = [valueC] // keyD = [valueD]
  20. Further topics to cover • Testing • Conjunction with LiveData

    and RxJava • Getting statuses of a worker • Cancelling and stopping workers • Existing workers - replace, keep, append • News in WorkManager - e.g. LongWorker
  21. Reference • Android Developer Documentation • Background work with WorkManager

    - Codelabs • WorkManager Basics - Article on Medium • InputMerger with WorkManager • https://github.com/bartoszostrowski/WorkManagerExample