WorkManager: Basics - MAD Skills

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] CAREN CHANG: Hello, and welcome to the first episode of our WorkManager series. WorkManager is now the recommended solution for long-running tasks. So in this episode of "MAD Skills," we'll take a closer look at how to get started with using the WorkManager APIs. By the end of the video, you'll know how to define, schedule, and chain work requests. We have a lot to cover, so let's get to work. To help you follow along, we're going to be using the WorkManager colab as a basis. Our goal in this colab is let the user blur an image. And we're going to be using the WorkManager API so that the blurring work can be done in the background. WorkManager is an Android Jetpack library that lets you schedule long-running tasks reliably. Previously, there are different job scheduling APIs. Some of these APIs only worked on specific Android versions or if Google Play services were installed. WorkManager works with all versions of Android since Ice Cream Sandwich regardless of whether Google Play services are installed. The other great thing about WorkManager is that you can schedule tasks to run based on certain constraints so that your task only runs when the constraints are met. You can also chain work requests so that jobs run sequentially depending on whether previous jobs were successful. All right, now that we know a little more about WorkManager, let's start looking at some code. In WorkManager, there are two main classes we care about-- the worker and the work request class. The worker class is where we're going to define the work we want to perform in the background. We do so by creating our own worker class and overriding the doWork method. This method runs asynchronously on a background thread, which means they won't block the user from interacting with the app while our work is being done. Here we created a BlurWorker that extends the worker class. We then override the doWork method to implement the work we actually want to schedule. In this case, we're taking an image as an input and blurring it with the createBlurredBitmap method. doWork should eventually return a result to let us know whether our work completed successfully. Notice that we can also include an output as part of the result. These result functions are overloaded and can also accept a WorkManager data object. Data serves as structured key value storage that you can pass around. The easiest way to build data is by using the workDataOf extension function. In this function, you can then map one or multiple keys to values and return them as part of the response. There is a hard upper limit to how many bites you can pass around with a data object. And our bitmaps are definitely above that limit. So instead of passing the bitmaps around, we're actually passing the URIs of the bitmaps. Here, we're using the URI of the newly blurred image as our output. By adding an output to our result, we can then use this output as an input for future tasks if we decide to chain multiple workers together. When we chain tasks together, the output from the first task will be available as an input to the next task. And we'll see this in action a little later. Having said all that, we should return success if our work was completed successfully. On the other hand, if the scheduled work was unsuccessful, we should return a failure result. In some cases, we might even want to return or retry result, which means something went wrong, but we should we retry this work at a later time. Once we've defined the work we want to do, we need to actually schedule it with WorkManager by using a work request. And we could take a look at how that's done in BlurViewModel. The WorkManager service is responsible for scheduling all the work that we request. And it takes into account the system's resources to ensure that the work is spread out evenly. The work request class allows us to define how and when we want our work to be executed. For example, we can specify this work to run periodically, only when the device is connected to WiFi and power. Here we've got a WorkManager instance, and we use it to create a one-time work request to execute the BlurWorker that we created earlier. We then enqueue this work request so that our job can actually run. Notice that we're using a one-time work request here. WorkManager can also help us run tasks periodically. For example, we might want to backup data once a week or download new data every 24 hours. To do this, we can use a periodic work request instead. But since we just need to blur this image once, one-time work request will get us the job done here. OK, so far we've scheduled work to blur the image. But this isn't very useful yet because we haven't actually saved the new image. If we remember, BlurWorker is currently outputting the URI of the newly blurred image. So now we have to take that URI and save it to a file. Luckily for us, WorkManager has a pretty easy way to chain multiple work requests together. By chaining requests together, we can first execute the work to blur the image. And then once that work is done, we can execute a second worker to save the blurred image to the file. Since we need some new work to be done, let's create a second worker that handles saving the file of the newly blurred image here in SaveImageToFileWorker. We didn't specifically need to create the second worker class, but it's good practice to keep separate workers for specific tasks to keep things clean. You can see here in doWork is where we implement saving the file. Our input data here will come from the output data of BlurWorker. And that's how we'll get the URI of the blurred image so that we can save it to a file. Now, navigating back to BlurViewModel, we need to create a chain of work requests. Now that we have more than one worker, we can use the then method to queue up the second work request after the first one has completed. Calling then allows us to run tasks sequentially. So first we blur the image, and then we save the image. This also means that the output data of the first work request will automatically be the input data of the second work request. If instead we wanted to run tasks in parallel instead of sequentially, we could use the listOf method instead. OK, great. Now that we've implemented the two work requests and chained them together, we'll actually be able to save the image we blurred. Our app can now blur and save an image. But we do have one small problem. If the user continuously taps on the Go button, they'll end up triggering a chain of work events multiple times, causing a lot of redundant work we don't want. To ensure that the work we schedule is unique, we can use the beginUniqueWork API instead of beginWith. You'll notice that beginUniqueWork asks us for a couple of extra arguments. First, we need to give a name to our unique work so that WorkManager knows how to detect duplicates. Then, we need to tell WorkManager what to do when duplicate work is detected. Here we have a few options. The first one is to replace the existing work in progress. This means that if WorkManager detects duplicate work being done, it will stop the work that was in progress and start a new one that was requested instead. Our second option is to keep the existing work. This means that a new work request will be ignored since there is already the same work being done currently. There's also the APPEND and APPEND_or_REPLACE strategy, which append the new work after the current work is done. Since we only need to blur the image once, we're going to use the KEEP strategy here. That way, our app will not start blurring another image until its current work is done. For a last step, it would also be nice to know when all this work we scheduled has finished running. We could do that by getting a live data that holds a list of work infos. Work info lets us know the status of a work request, whether it's blocked, canceled, enqueued, failed, running, or succeeded. These different states can be helpful in letting us know if our work was completed successfully, or if we need to retry it. And get these work infos in three different ways-- using the unique ID of a work request, using the work request's unique chaining, or using the tag of a name of a work request that we add. For our app, we're going to add a tag to our work request so that we could query for the work info. Now outputWorkInfoItems is getting live updates about the status of our work requests for the TAG_OUTPUT tag. Our next goal is to show a loading indicator when work is currently running. So in our blur activity, we should observe a list of work infos. Since we only need to know if the work is in progress, we can use isFinished method. isFinished returns true when the work has either succeeded, failed, or been canceled. So it's not a guarantee that the work was successfully done, but it's good enough to let us know whether the work is still in progress or not. And with that final touch, our image blurring app is in pretty good shape. Now that we've learned how to schedule work, let's take a quick look to understand how WorkManager schedules these tasks. Since WorkManager can schedule deferrable tasks that don't need to run immediately, if your app is not currently active, it's not a guarantee that your scheduled work will be executed immediately. Based on which apps standby bucket your app has been placed in by the system, your scheduled work may be deferred. Since our image blurring app requires the user to click a button in the app to start blurring the image, the work will not be differed since the app is active when the requested work is scheduled. However, if our image blurring work was scheduled to run periodically without a user prompt, the work could be deferred based on how often our app is used. After a bit of work, we were able to create our first work request to blur and save the new image. Along the way, we learned how to chain requests, to find unique work, and resolve potential conflicts. Now that we've explored the basics of the WorkManager API, it's time for you to give it a try in your own app. We've added some links down in the video description from our resources to help you get started. And that concludes our work for now. Be sure to tune into the next episode, where we'll be looking at some more advanced usages of WorkManager. [MUSIC PLAYING]
Info
Channel: Android Developers
Views: 20,945
Rating: 4.9285712 out of 5
Keywords: GDS: Yes, workmanager apis, introduction to workmanager, workmanager, what is workmanager, how to use workmanager, android workmanager, android developers workmanager, how to workmanager, workmanager how to, workmanager basics, workmanager basic usage, workmanager threading, workmanager custom configuration, migrating deprecated code, developer, mad skills, android developers, android developer, android, google, Caren Chang
Id: _SQM-10TB4k
Channel Id: undefined
Length: 10min 16sec (616 seconds)
Published: Mon Mar 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.