Is there a way to enqueue work in work manager from multiple processes? Right now I’m getting this message when I’m trying to do it from the "non-ui" process
I/WM-GreedyScheduler: Ignoring schedule request in non-main process.
Work manager version I'm using is 2.4.0. I know there is 2.5.0-alpha2 right now, but I cannot use that in production
WorkManager 2.5.0-alpha02 is the first version of WorkManager that has multi-process support.
There is no mechanism for using WorkManager across multiple processes in any previous version of WorkManager (hence why these new APIs were added in the first place) so you'll need to either upgrade to that version of WorkManager or wait for it to become beta/RC/stable.
Related
Android 12 brings restrictions on foreground service usage and dev team offers a WorkManager as an alternative.
Google team wrote a good article on what should be used and when. My use case is close to long-running operations which is covered here. However, it requires to define a category of service type which seems doesn't cover my use case.
My use case is to run minting a token from mobile wallet on ethereum chain and wait for callback. I use privately hosted eth chain which mines a block each 15 seconds. Keeping in mind this time schedule might increase in future depends on changes in business requirements I want the app to support a longer request even at this stage of the development. That's why I need to run it as a long running operation.
FOREGROUND_SERVICE_TYPE_SPECIAL_USE looks like a right fit, but it is supported only on the latest SDK. Compilation under the my current compile SDK (33) supports only this options
[camera=64, connectedDevice=16, dataSync=1, location=8, mediaPlayback=2, mediaProjection=32, microphone=128, phoneCall=4]
That's from an error shown by compiler.
Android compileSdk = 34 is not supported, but anyway it is still under preview. This limited options from the compiler error messages tells me I WorkManager long running operations are not a good fit for my use case. Altogether it brings me to the questions:
Which type of foreground service type should I choose?
Shall I reject WorkManager for this use case at all?
What could be an alternative for WorkManager on post Android 12 devices for foreground-service operations?
So I know WorkManager utilizes JobScheduler on supported APIs but there doesnt seem to be any way to make WorkManager work persistent across reboots? Is the only option to request the BOOT_COMPLETED permission and reschedule jobs?
To answer your question: You don't need to do anything if the device is rebooted. WorkManager keeps scheduling your Work without any additional requirement from your side.
WorkManager persists Work requests in its internal Room database. This allows it to guarantee Work execution across device restart.
The documentation covers this as this blog "Introducing WorkManager" that the team wrote last year.
WorkManager is actually used to persist deferrable tasks even after your app exits and the device restarts, please refer to the docs. It uses JobScheduler for api 23 and above and broadcastReceiver and AlarmManger on api 14 to 22. You can use constraints to check battery status, network coverage ...etc depending your particular usecase. You just have to be careful not to remove or rename your existing classes after they are added in the queue because WorkManager uses it's internal database to store those classes and your app will crash if you remove them or rename them.
I wonder why should I bother with rx or coroutines when there is brilliant solution as WorkManager. But for almost all tutorials they use coroutines so may be WorkManager has disadvantages ?
The scope of both is different. WorkManager is to schedule deferrable (for any later time) or immediately.
tasks asynchronously.
As documentation says
The WorkManager API makes it easy to specify deferrable, asynchronous
tasks and when they should run. These APIs let you create a task and
hand it off to WorkManager to run immediately or at an appropriate
time.
On the other hand, coroutines are designed to compute a given task only immediately and asynchronously.
Also
Internally, coroutines and WorkManager work differently. Work manager heavily depends on Android system components like Services, Alarm manager, etc to schedule the work whereas coroutines schedule the work on Worker Threads and also is a language feature unlike WorkManager (API). So it is safe to say that coroutines do not go beyond your application. On the other hand, WorkManager can even execute the given tasks when your application is not active. for instance, background services.
Also as Marko answered, using coroutines will lead to better code readability and quality due to their fundamental design.
I would also like to include ANKO, Its a great library that provides a helpful API around coroutines for Android.
Background tasks fall into one of the following main categories:
Immediate
Deferred
Exact
To categorize a task, answer the following questions:
Does the task need to complete while the user is interacting with the application?
If so, this task should be categorized for immediate execution. If
not, proceed to the second question.
Does the task need to run at an exact time?
If you do need to run a task at an exact time, categorize the task as
exact.
Most tasks don't need to be run at an exact time. Tasks generally allow for slight variations in when they run that are based on conditions such as network availability and remaining battery. Tasks that don't need to be run at an exact time should be categorized as deferred.
Use Kotlin Coroutine when a task needs to execute immediately and if the task will end when the user leaves a certain scope or finishes an interaction.
Use WorkManager when a task needs to execute immediately and need continued processing, even if the user puts the application in the background or the device restarts
Use AlarmManager when a task that needs to be executed at an exact point in time
For more details, visit this link
If your goal is writing clean code without explicitly constructed callbacks you pass to background tasks, then you'll find that coroutines are the only option.
Using coroutines by no means precludes using WorkManager or any other tool for background operations of your choosing. You can adapt the coroutines to any API that provides callbacks as a means to continue the execution with the results of background operations.
From official Documentation:
It is important to note that coroutines is a concurrency framework, whereas WorkManager is a library for persistent work.
WorkManager:
Support for both asynchronous one-off and periodic tasks
Support for constraints such as network conditions, storage space, and charging status
Chaining of complex work requests, including running work in parallel
Output from one work request used as input for the next
Handles API level compatibility back to API level 14(see note)
Works with or without Google Play services
Follows system health best practices
LiveData support to easily display work request state in UI
Waits proper time to run.
Coroutines:
Clean code, works under the hood in a different way. Run immediately.
So depending on your requirements choose the better option.
Has others replied, WorkManager solves a different problem than Kotlin's corountines or a reactive library like RxJava.
WorkManager is now available as beta and additional documentation is produced that hopefully makes this clear.
One of these documents is the blog post I worte with some colleagues: Introducing WorkManager, where you can read:
A common confusion about WorkManager is that it’s for tasks that needs to be run in a “background” thread but don’t need to survive process death. This is not the case. There are other solutions for this use case like Kotlin’s coroutines, ThreadPools, or libraries like RxJava. You can find more information about this use case in the guide to background processing.
I was learning about JobScheduler with a Tutorial from 2015, and when I was creating a class of this service,it complains asking me to put the annotation #RequiresApi(api = Build.VERSION_CODES.LOLLIPOP), which means, doesn't work for old versions? And if it is, GCMNetworkManager would be the one ?
which means, doesn't work for old versions?
Yes annotation specifies that API wont work under LOLLIPOP version
And if it is, GCMNetworkManager would be the one ?
Alternatives to JobScheduler are
AlarmManager
GCMNetworkManager
SyncAdapter
You should choose one that suits your need with minimal device resource utilisation.
Note: Avoid using services that run perpetually or perform periodic work, since they continue to use device resources even when they are not performing useful tasks.
In my android app I have created a function that updates some fields in SQLite database, now I run this function manually and it is doing the job, but I want to run this function automatically once in a month. How it is possible.
To run your task periodically i recommend you to take a look at it JobScheduler api which is latest and more powerful for scheduling the job take a look at this https://developer.android.com/reference/android/app/job/JobScheduler.html
if your app targets api >21 you must use jobscheduler if u want to support the lower version take a look at firebase job dispatcher:https://github.com/firebase/firebase-jobdispatcher-android