WorkManager – PeriodicWorkRequest

Reading Time: 9 minutes

In this WorkManager basics tutorial we are going to learn about how we can create PeriodicWorkRequest. It means, that the work going to run in the background periodically even if we have closed the application.

One time WorkRequest

Previously we have talked about how you can create one time WorkRequest. It means the work will be fired when an event happen. In our sample pizza delivery tracker app, when the Activity startes will fire the one time WorkRequest.

In this tutorial you can learn also how you can chain workers after each other. It means that the next work will be started when the predecessor work has been finished successfully.

You can check out this tutorial using the below link

WorkManager basics – Periodic request

What is WorkManager?

WorkManager is part of the Android Jetpack library. It runs deferrable guaranteed backround work.

A deferrable task is one that doesn’t need to be executed immediately and may depend upon some constraints such as network conditions, storage space, and charging status.

A work can have different constraints, which determines the conditions when the work can be executed. A WorkManager’s work runs in the background even if the app is closed.

WorkManager has support for one time and periodic asnychronous execution as well.

Periodic execution means, that the next task will be fired when the previous task is successfully finished.

In the consciousness of these conditions, we can see thet WorkManager provides a battery-friendly API.

Battery-friendly, because it executes the tasks when it is the best to save the life of the battery avoiding unncessery wake-up for the phone. This is realy important for Android applications that need to execute background tasks!

When to use WorkManager?

When we need to do a long running task. This task can be started in the background, or also when the app is in the foreground, but needs to be done in the background, or during the execution the Android system kills its process.

WorkManager is not about run in a background thread. For this use cases you should use Kotlin Coroutines or libraries like RxJava.

The sample app

In this tutorial we are going to create a very simple application. As you can see on this picture, the user interface will contain a TextView and 3 Buttons.

The TextView will show us when our WorkRequest was fired.

With the Buttons below we can start, stop and clear the already saved data in case if we want to restart the period.

WorkManager - PeriodicWorkRequest

Step 1 – Create new project

Our first task is to create a whole new project. For this, launch Android Studio. If you see the “Welcome page”, then click on the “Start a new Android Studio project”. If you have an open project, then from the “File” menu select “New”, then “New Project”. After thet, this window will popup.

Here select the “Empty Activity” option. In the next window, we should provide some information about the newly created app.

This tutorial will contain very few code, but still we have to select the programming language. As the other tutorials on this website, this will be written also in Kotlin. So, select from the dropdown list the Kotlin language.

From the next list of the “Minimum SDK” select API 21. In our case API 21 gonna be enough.

If you are done, click on the “Finish” button. The build can take few minutes. Be patient! 😉

When the build has been finished, then you should see the open MainActivity::class and next to this the activity_main.xml files.

Step 2 – Add the dependencies

In our sample application we are going to create workers and a ViewModel as well. So, in order to implement them, we need to add 2 depencendies to our project.

We can do it as follows. Open up the App Build.gradle file from the left Project pane.

Next, paste the below implementations into the dependencies {} section.


The needed dependencies

JVM target

The WorkManager library targets the version 1.8 of Java Virtual Machine. So, we have to tell for Android Studio that we would like to use the version 1.8. To do this, stay in the App Build.gradle file and paste the below lines to the end of the android {} section.


JVM version 1.8

Thenafter click on the Sync now button, what you can find in Android Studio at the top left corner.

Step 3 – The UI of MainActivity

For the MainActivity we will have a very simple user interface, because it will contain a TextView and 3 Buttons.

So, just copy and paste the below xml code into the activity_main.xml file. You can find it in the res->layout folders.


activity_main.xml

Step 4 - SharedPreferencesRepository

To store the Date, when the WorkManager executed, we gonna use SharedPreferences. Using SharedPreferences, we can store relativly small collection of key-value pairs, where the key is used to get the store value from SharedPreferences.

For SharedPreferences we gonna create a repository package, which will contain the SharedPreferencesReposity::class. Inside of this class we gonna define the needed functions to manipulate the stored Date values. So, first create a package inside of the main source set and name it as repository. Then create inside of it the SharedPreferencesReposity.kt Kotlin file.

If you have created the package and Kotlin file, then paste the below lines into the SharedPreferencesReposity.kt file.


SharedPreferencesRepository::class

      1. To initialize SharedPreferences we need the context, what we are going to pass in the constructor of the class.
      2. The needed constants.
        The first one is to identify the shared preferences.
        The second one is the key of the saved data.
      3. Initialization of SharedPreferences.
      4. Saving the Date String.
      5. Get back the saved Date Strings
      6. When we would like to restart the collection, then we can clear the saved shared preferences.

Step 5 - SharedPreferencesRepository

To store the Date, when the WorkManager executed, we gonna use SharedPreferences. Using SharedPreferences, we can store relativtly small collection of key-value pairs, where the key is used to get the store value from SharedPreferences.

For SharedPreferences we gonna create a repository package, which will contain the SharedPreferencesReposity::class to Inside of this class we gonna define the needed functions to manipulate the stored Date values. So, first create a package inside of the main source set and name is as repository. Then create inside of it the SharedPreferencesReposity.kt Kotlin file.

If you have created the package and Kotlin file, then paste the below lines into the SharedPreferencesReposity.kt file.


SharedPreferencesRepository::class

    1. To initialize SharedPreferences we need the context, what we are going to pass in the constructor of the class.
    2. The needed constants.
      The first one is to identify the shared preferences.
      The second one is the key of the saved data.
    3. Initialization of SharedPreferences.
    4. Saving the Date String.
    5. Get back the saved Date Strings
    6. When we would like to restart the collection, then we can clear the saved shared preferences.

Step 6 - The Worker

The next step is to build up the Worker. This Worker class going to be executed. Inside of this class we have to implement the doWork() method. Inside of this method, we gonna have the code what should be executed periodically by WorkManager, which is in our case to save the Date and the Time to shared preferences.

So, create a new package in the main source set and name it as “workers”. Then, into this new package create a new Kotlin file with the name of “LogWorker”.

Thenafter copy and paste the below Kotlin code into the LogWorker::class. After thet we gonna go into the details.


LogWorker::class

    1. We have to define a tag variable. Using this tag later on in the ViewModel class we can identify the WorkRequest to start and also to cancel it.
    2. To create a Worker class we have to add the constructor to the header of the LogWorker::class with the Context and the WorkerParameters. These variables are needed for the Worker::class, which is the super class of LogWorker::class.
    3. Create an instance for the SharedPreferencesRepository::class
    4. To override the doWork() method is mandantory.
    5. In case if we have a code, which can fail, then we can catch and tell WorkManager to retry it again in a later time.
    6. Get the already saved shared preferences.
    7. Then extend it with the current date and time.
    8. Finally, if everything worked as espected, then we can return with a successful answer.

Step 7 - The ViewModel

In this step we are going to add to our project the ViewModel following the MVVM design pattern. It means, thet we won’t have the WorkManager created in the Activity/Fragment, nor the instance for the shared preference’s repository. We will have them in the ViewModel class. Later on, we gonna call the methods of this ViewModel from the lifecycleowner, which is in our case the MainActivity.

So, as we have done it before, create a new package in the main source set and name it as “viewmodel”. Then inside of this new package create a new Kotlin file with the name: “PeriodicWorkViewModel”.

The constructor

Next, extend the PeriodicWorkViewModel::class with the constructor. We need the Application instance to create an instance for the shared preferences repository.


Header of the viewmodel

Member variables

Thenafter add the below 2 member variables to the viewmodel.


Member variables of the viewmodel

Note the first member variable. In this way we can create an instance for the WorkManger using the context, which is in our case the context of the whole application.

In the following methods we gonna use it to create WorkRequests and cancel them.

Start periodic work

Next we are going to create a method which will be fired, when we would like to start the periodic WorkRequest.

We can create returning WorkRequest using the PeriodicWorkRequestBuilder() method passing through the LogWorker::class. Using this method we have to tell for WorkManager how offen we need the exection of our work. In our case it will be fired every 15 minutes.

Using the builder method, we can specify tags also. Later on with this tag, we can cancel the periodic WorkRequest and also get back some output from our worker class.

Still in this method, we gonna enqueue our unique periodic work using our workManager instance. For this we have to give a name for the unique work.

We have to also specify the work policy. It tells for WorkManger what should be done with the already running WorkRequests. In our case, we gonna replace it.

If you would like to know more about the rest existing work policies, then check out the below link.

ExistingWorkPolicy

Finally, paste the below method after the member variables.


startPeriodicWork()

Start periodic work

To stop our periodic work is realy simple, we should just call the cancelAllWorkByTag() method of WorkManager.

So, paste the below method at the end of the PeriodicWorkViewModel::class.


stopPeriodicWork()

Get and clear shared preferences

The last 2 methods of the viewmodel will get back the shared preferences and clear it. We gonna call these methods from the MainAcitivty. So, paste the below methods also at the and of the viewmodel.


get and clear shared preferences

Step 8 - The MainActivity

In the last step we are going to add some code to the MainActivity. So, open it from the main source set.

First, add the below variable of the PeriodicWorkViewModel::class before the onCreate() method.


periodicWorkViewModel

Thenafter initialize it in the onCreate() method.


init periodicWorkViewModel

Next add the below line at the end of the onCreate() method. This will get the saved shared preferences and set the text of the TextView when we open the app.


update the TextView

Finally the 3 click listeners for the 3 Buttons. The first will fire our periodic work. The second one will stop it. The third one will clear the shared preferences.


The click listeners

Run the app

Finally, run the app and test it. 😎

GitHub

The source code is available on GitHub, check it out and download it using the below link.

GitHub

Questions

I hope the description was understandable and clear. But, if you have still questions, then leave me comments below! 😉

Have a nice a day! 🙂

Follow and like us:

Click to rate this post!
[Total: 0 Average: 0]

Leave a comment