Monday, 7 November 2022

Android Work Manager

     


Android Work Manager




watch this video



Android WorkManager could be a backgrounding library that is employed to execute background tasks that ought to run during a warranted method however not essentially forthwith. With WorkManager we are able to enqueue our backgrounding even once the app isn't running and also the device is rebooted for a few reason. WorkManager additionally lets United States of America outline constraints necessary to run the task e.g. network accessibility before beginning the background task.

Android WorkManager could be a a part of humanoid Jetpack (a suite of libraries to guide developers to put in writing quality apps) and is one amongst the humanoid design parts (collection of parts that facilitate developers style strong, testable, and simply rectifiable apps).

When to use WorkManager while working with background processing?

With the evolution of robot OS over the years, there square measure restrictions placed on priority processing, so as to optimize battery consumption associate degreed build use of device resources in an best approach. every new robot unleash, ranging from robot candy (API 23), has else some restrictions. you'll examine the precise details on identical within the robot developer guide.

Thus, it's necessary to settle on the most effective priority processing approach for your app per your desires. Let’s quickly say cases once you would value more highly to use WorkManager.

Android WorkManager will be an ideal priority processing library to use once your task –

  1. doesn't have to be compelled to run at a selected time
  2. will be delayed to be dead
  3. Is sure to run even when the app is killed or device is restarted
  4. should meet constraints like battery offer or network availableness before execution

The simplest example for this will be once your app has to transfer an outsized chunk of user knowledge to the server. This explicit use case meets the factors we have a tendency to mentioned higher than to settle on WorkManager because:

  1. Results needn't be mirrored instantly in your robot app
  2. knowledge has to be transfered even once the upload begins and therefore the user kills the app to figure on another app, and
  3. The network has to be accessible so as to transfer knowledge on the server.

Creating a background work with Android WorkManager

To get started with implementing WorkManager, we tend to 1st have to be compelled to produce a piece that defines the task we want to run within the background victimisation WorkManager. For brevity, we'll think about uploading user knowledge to server as our use case throughout this text. To outline work, we'll produce category|a category} that extends the employee class. The task to be performed in background is written within the overridden methodology doWork().

The code below shows associate example of the way to write a employee category.

import android.content.Context import androidx.work.Worker import androidx.work.WorkerParameters class UserDataUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { uploadUserData() return Result.success() } private fun uploadUserData() { // do upload work here } }

Working with WorkRequests

After we have a tendency to outline our work, we have a tendency to currently got to outline however and once we ought to begin the work. one in all the benefits of exploitation WorkManager is that we are able to outline whether or not our work could be a one-time task or the work has to be referred to as sporadically.

OneTimeWorkRequest

OneTimeWorkRequest may be a concrete implementation of the WorkRequest category that is employed to run WorkManager tasks that area unit to be dead once. The code below shows a way to produce OneTimeWorkRequest in its simplest kind

val uploadWorkRequest = OneTimeWorkRequestBuilder<UserDataUploadWorker>().build()

In order to run this work request, we'd like to decision enqueue() technique on Associate in Nursing instance of WorkManager and pass this WorkRequest as shown below:

WorkManager.getInstance().enqueue(uploadWorkRequest)

The enqueue() technique enqueues one or a lot of WorkRequests to be run within the background.


PeriodicWorkRequest

PeriodicWorkRequest, because the name suggests is employed to run tasks that require to be known as sporadically till off.

A few details to stay in mind once operating with PeriodicWorkRequest:

  1. The work is run multiple times
  2. The work keeps on death penalty sporadically till it's off
  3. the primary execution happens directly when the mentioned constraints ar met and also the next execution happens when the mentioned amount of your time
  4. revenant execution doesn’t begin if the constraints mentioned thereupon work request aren't met
  5. The minimum repeat interval is quarter-hour
  6. The work can not be enchained with different work requests
  7. The measure between two periodic intervals will disagree supported OS improvement restrictions we have a tendency to saw earlier

A PeriodicWorkRequest will be dead as shown below:

val periodicWorkRequest = PeriodicWorkRequestBuilder<UserDataUploadWorker>(24, TimeUnit.HOURS).build()
WorkManager.getInstance().enqueue(periodicWorkRequest)

The code on top of creates a periodic work request that is dead each twenty four hours.

In order to prevent the execution of periodic work, it must be expressly cancelled:

WorkManager.getInstance().cancelWorkById(periodicWorkRequest.id)


Constraints in Android WorkManager


WorkRequests can even be engineered with some constraints that require to be glad so as to execute the task. Constraints in WorkManager ar specifications regarding the necessities that has to be met before

the work request is dead. For our use case, if we'd like to transfer user knowledge on our server, having network handiness may be a should. Thus, through the work request constraints, we will certify that our transfer task is dead only the network is on the market as shown below:

val uploadDataConstraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() val oneTimeWorkRequest = OneTimeWorkRequestBuilder<UserDataUploadWorker>() .setConstraints(uploadDataConstraints) .build()

There area unit several different constraints accessible with automaton WorkManager together with ‘requires charging’, ‘storage isn't low’, ‘device isn't idle’, etc. a listing of of these constraints will be found below:

val constraints = Constraints.Builder() .setRequiresBatteryNotLow(true) .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(true) .setRequiresStorageNotLow(true) .setRequiresDeviceIdle(true) .build()

One work request will have multiple constraints outlined thereon. just in case of multiple constraints, the work is dead only all the constraints square measure met. If any constraint isn't glad, the work is stopped and resumed only that constraint is met.

Input Data, employee Results, and Output knowledge in WorkManager
Input Data

Running your background task typically wants some information to figure on. Like in our example, if we would like to send user information to the server via a employee, we'd like to pass that user information to the employee task. In automaton WorkManager, we will do therefore by mistreatment the info category. The computer file is nothing however an inventory of key-value pairs. the info are often passed to the WorkRequest as shown below:

import androidx.work.* .... val userDataJson = "{some data...}" val someOtherData = false // using workDataOf() method from KTX val inputWorkData = workDataOf("user_data" to userDataJson, "other_data" to someOtherData) // using Data.Builder val inputData = Data.Builder() .putString("user_data", userDataJson) .putBoolean("other_data", someOtherData) .build()val oneTimeWorkRequest = OneTimeWorkRequestBuilder<UserDataUploadWorker>() .setConstraints(uploadDataConstraints) .setInputData(inputData) .build()

As seen within the code higher than, the info will be made in a pair of ways:

  1. By mistreatment workDataOf() technique that is a component of KTX and that converts list of pairs as information
  2. By mistreatment the info.Builder category that constructs a map from the passed key-value pairs and builds information from this map

In order to access this computer file within the employee, getInputData() is named within the doWork() technique to extract individual values from their keys like this:

import android.content.Context import androidx.work.Worker import androidx.work.WorkerParameters class UserDataUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { // fetch the input data just like you would fetch values from a map val userDataJson = inputData.getString("user_data") val someOtherData= inputData.getBoolean("other_data", false) // pass false as default value uploadUserData() return Result.success() } private fun uploadUserData() { // do upload work here } }

Worker Results and Output Data

Result category is employed to come back the standing of our employee task. doWork() methodology of the employee category that is overridden to try and do the background tasks, expects AN object of sophistication Result as its come back sort. Work Result may be of 3 types:

  1. Result.success() – This result indicates that the work was completed with success
  2. Result.failure() – This result indicates that the work was for good terminated which if there's any chain of employees following this employee, all the subsequent employees will be terminated. therefore we should always come back Result.failure() only our chain of employees relies on this worker’s output
  3. Result.retry() – This result indicates that the work is terminated for a few reason which it ought to be retried/ re-executed

Great, therefore what if we have a tendency to conjointly wish to pass some output knowledge back from the employee once our priority processing is over?

The ways, success() ANd failure() of the Result category absorb knowledge as an argument. This knowledge is same because the one used for computer file and might made within the same manner, with a listing of key-value pairs.

An example of passing output knowledge from employee is shown below:

import android.content.Context import androidx.work.Worker import androidx.work.WorkerParameters import androidx.work.workDataOf class UserDataUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) { override fun doWork(): Result { val isSuccess = uploadUserData() val outputData = workDataOf("is_success" to isSuccess) return Result.success(outputData) } private fun uploadUserData(): Boolean { // do upload work here return true } }

But however does one access this output information from the Worker?

If you follow humanoid developer’s official documentation, you may try and extract the output by victimization WorkInfo like this:

val workInfo = WorkManager.getInstance().getWorkInfoById(oneTimeWorkRequest.id).get() val wasSuccess = workInfo.outputData.getBoolean("is_success", false) Toast.makeText(this, "Was work successful?- $wasSuccess", Toast.LENGTH_LONG).show()



If you execute the code higher than, can|you'll|you may} notice that the output information isn't passed from the employee and therefore the technique getBoolean() on outputData will simply resort to returning the default worth i.e. false. we will check if we've so passed output information from the employee however the behaviour still remains a similar.

The reason behind not obtaining any output information is that the employee executes all the tasks in background synchronously. after we commit to fetch the output information from the WorkInfo, we tend to attempt to fetch the output information before the employee is even dead. you'll be able to check this by running getStatus() technique on the WorkInfo instance.

WorkManager.getInstance().getWorkInfoById(oneTimeWorkRequest.id).get().state

Calling the state forthwith when enqueuing the WorkRequest can offer the state as ENQUEUED and thence don’t get any output information.

To get the output information, we'd like to watch the WorkInfo via LiveData so our app can commit to retrieve the output information only the employee is finished with its execution.

Observing Worker state via LiveData in WorkManager

Android WorkManager helps you to observe the states of the employee by returning LiveData for the requested WorkInfo and perceptive this LiveData for any changes. Thus, currently to access the output information, we'd like to write down Associate in Nursing observer on the WorkInfo LiveData, check if its state is SUCCEEDED, then extract the output information. Check the code below

WorkManager.getInstance() .getWorkInfoByIdLiveData(oneTimeWorkRequest.id).observe(this, Observer { workInfo -> val wasSuccess = if (workInfo != null && workInfo.state == WorkInfo.State.SUCCEEDED) { workInfo.outputData.getBoolean("is_success", false) } else { false } Toast.makeText(this, "Work was success: $wasSuccess", Toast.LENGTH_LONG).show() })

Closing Thoughts

To summarise, we have a tendency to looked at:

What golem WorkManager is
When precisely to use WorkManager (for background processing)
How to execute it and applying constraints
Passing information to and from the WorkManager employees
Observing WorkManager task for output information


No comments:

Post a Comment

H

H

H

H

H

Hi

Contact Form

Name

Email *

Message *

Search This Blog

Popular Posts