Android. Is WorkManager running when app is closed?
Asked Answered
D

3

88

I want to schedule nightly database updates. So I use new Android WorkManager. My understanding is that once scheduled it will always run in the background independently from the app's lifecycle. Is that right? My first tests show that Work is only being performed when the app is running.

val locationWork = PeriodicWorkRequest.Builder(UpdateDatabaseWorker::class.java, 24, TimeUnit.HOURS)
                        .addTag("DATABASE_UPDATE_SERVICE")
                        .build()
WorkManager.getInstance().enqueue(locationWork)
Decimal answered 4/6, 2018 at 13:43 Comment(0)
E
154

Based on various issues reported on the WorkManager bugtracker, their documentation is not completely precise about the exact behavior of the WorkManager in such edge cases.

On certain devices, apps are force stopped when the app is cleared from task manager, so that part is expected. ... source


Unfortunately, some devices implement killing the app from the recents menu as a force stop. Stock Android does not do this. When an app is force stopped, it cannot execute jobs, receive alarms or broadcasts, etc. So unfortunately, it's infeasible for us to address it - the problem lies in the OS and there is no workaround. source


The only issue that we have come across is the case where some Chinese OEMs treat swipe to dismiss from Recents as a force stop. When that happens, WorkManager will reschedule all pending jobs, next time the app starts up. Given that this is a CDD violation, there is not much more that WorkManager can do given its a client library. source


To add to this, if a device manufacturer has decided to modify stock Android to force-stop the app, WorkManager will stop working (as will JobScheduler, alarms, broadcast receivers, etc.). There is no way to work around this. Some device manufacturers do this, unfortunately, so in those cases WorkManager will stop working until the next time the app is launched. source


With intense testing of a OneTimeWorkRequest (without constraints) on a Pixel 2 XL with stock android the behavior is the following:

  • Task manager close:
    • Work continues (after a bit)
  • Reboot device (work running):
    • Work continues after reboot done
  • App info "Force stop":
    • Work stops, will only continue when app is started again
  • Reboot device (work was "Force Stopped"):
    • Work does not continue until the app is started again

You can find a complete list of different OEM behaviors on dontkillmyapp.com. It seems the Android team also acknowledges this issue and added a test for this into their CTS test for Android Q. source

Emileeemili answered 2/10, 2018 at 9:20 Comment(20)
What's the difference between rebooting the device (work running) and reboot (work was force stopped)? In both cases the work was running when the device was rebooted.Viewfinder
On my Nexus 6P, if I restart the device when no work is being done but is scheduled to run in the near future, it will never run until the app starts. I tested this using OneTimeWorkRequest. However, if the app is running and the worker is not running but is scheduled to run in the near future but you swipe the app to close it by removing it from the Recent menu, it will start at the scheduled time.Viewfinder
@AndroidDev yes "standard" Android will allow it to be run if you swipe it in the recents menu away, because it will not force kill the app. but samsung does a force kill for example. for the reboot. which Android version do you have running there, also which version of workmanager. that might affect thigns tooEmileeemili
@AndroidDev "force stop" is relevant. as "force stop" kills the complete process and prohibits it from automatically starting itself. just listed it for the complete pictureEmileeemili
The only issue that we have come across is the case where some Chinese OEMs treat swipe to dismiss from Recents as a force stop. When that happens, WorkManager will reschedule all pending jobs, next time the app starts up. - what to do with this?Thoth
@PavelPoley there is nothing you can do about this. It is the specification of the android system. The app and process has no way to work around this as it is a hard restriction. This also ensures if you force stop an app, it stays stopped and your phone will work even with many crappy appsEmileeemili
But how serious app like whatsapp/telegram handle it?Thoth
If you force kill the app then it won't be able to do background work. But (I believe) it is possible that it gets the notification from the FCM and if the user interacts with the notification it will start the app (I never tried this particular scenario though, so take this comment with a grain of salt)Emileeemili
@PavelPoley this might be of interest to you: twitter.com/MishaalRahman/status/1157018130012676101?s=19Emileeemili
Nice to see that they've simplified things with WorkManager.Chunchung
@Emileeemili I wasted lost of time on Vivo device and stopped after reading your answer. This is very big limitations. I wonder how social media app is managing to sync with server if WorkManager is not working when killed. Is there any other technique ?Herb
Is this still the case in 2020?Kohler
Killing app process doesn't launch a periodic job. Running on Pixel 2 emulator, API 28. Confused.Rodeo
@Rodeo exactly. if force stopped the task will no longer executeEmileeemili
@Kohler the rules are actually to enhance battery life and prevent unknown apps / malicious apps to run if they shouldn't. give the user the controlEmileeemili
@mikepenz, how is clearing recents tasks considered as a bad action? Every user does that periodically, does that mean that all of scheduled jobs should not be executed? Then in which case will jobs be executed? Only in case when user launched app at least once and has never cleared recent tasks list?? Makes no sense for me.Rodeo
I'm killing app process on behalf of system (i.e. process kill scenario, when data should be saved inside bundle and restore upon next launch). If system is in resources shortage and app process is killed by system - job won't be run in that case as well. I'm curious what's the purpose of WorkManager then?Rodeo
@Rodeo If you are killing the app on your own - on behalf of system, then there is no SavedStateHandle to speak of. Only if the system kills the app itself, can you use the Bundle. This behavior was confirmed by Google.Kohler
@Kohler "If you are killing the app on your own" I mean doing that via adb command, as if system killed the process. How would you test process kill scenario otherwise?Rodeo
Does anyone know what are the ideas in the video around 8:40? The guys are saying: "Come talk to us. We have some ideas". :D youtube.com/…Laud
W
6

My understanding is that once scheduled it will always run in the background independently from the app's lifecycle. Is that right?

Yes. Based on the documentation

The task is still guaranteed to run, even if your app is force-quit or the device is rebooted.

WorkManager chooses the appropriate way to run your task based on factors such as the device API level and the app state. If WorkManager executes one of your tasks while the app is running, WorkManager can run your task in a new thread in your app's process. If your app is not running, WorkManager chooses an appropriate way to schedule a background task--depending on the device API level.

WorkManager might use JobScheduler, Firebase JobDispatcher, or AlarmManager depending on the API level. It will repect the Doze and conaider all other constraints before executing the Work. You can expect some delay in Doze mode since it could wait for maintenance window.

Note:

WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.

Wilie answered 4/6, 2018 at 13:51 Comment(7)
So it is enough to enqueue task only once and it will run forever until explicitly cancelled? What I observe is that it only runs once and when app is running.Decimal
@TuesdayFourAM Yes. It is enough. It should run every 24 hours. You have to understand that for API > Lollipop. It will use JobScheduler to schedule the job. It will respect the Doze mode and the task will be executed during maintanance windowWilie
i tried and enqued a OneTimeWorkRequest in my worker i put a simple log and a thread sleep it was working fine but as soon i exit the app by swipping , there were no more logs.. so for me it seems like it stopped..Killam
What happens if we update the app with a new logic for the worker task? Will the already queued tasks be updated with the new logic?Copperhead
In my Android 9 device, work manager did not work when I closed the app. But I really need that my service work always.Telega
my constraints is .setRequiredNetworkType(NetworkType.CONNECTED). I triggered my job when off line and closed my app. I waited a few minutes and reestablished internet connection while app was closed and NO JOB was executed. Job was only executed when app restarted.Gorges
This is only true if you use enqueueUniquePeriodicWorkKohler
I
3

This is what documentation is saying:

Note: WorkManager is intended for tasks that require a guarantee that the system will run them even if the app exits, like uploading app data to a server. It is not intended for in-process background work that can safely be terminated if the app process goes away; for situations like that, we recommend using ThreadPools.

But there must be some condition. if that condition meet then WorkManager will run the task (this is important). Conditions like "only while device is charging and online"

Read this carefully, The WorkManager attempts to run your task at the interval you request, subject to the constraints you impose and its other requirements.

Here I found a good tutorial about how to use WorkManager for scheduling tasks : https://android.jlelse.eu/how-scheduling-work-with-new-android-jetpack-component-workmanager-852163f4825b

Indefinite answered 4/6, 2018 at 13:53 Comment(8)
So if like in my case I run a task without conditions it will always run?Decimal
@TuesdayFourAM no it will not run. You need to set some condition when that condition will meet it will run your task. For example; upload my photos to server when connected with Wifi.Indefinite
@TuesdayFourAM Welcome!Indefinite
I've added .setRequiredNetworkType(NetworkType.NOT_REQUIRED) to the work definition and it didn't help. Work was launched only once and then never run again. So, I still don't really understand how it works.Decimal
I was following the tutorial that you added in your comment and also posted this question to the author of the tutorial.Decimal
@TuesdayFourAM What device are you testing on? It may be that some vendors violate CTS (Compatibility Test Suite) too much. Try downloading the suite and testing your device to see the report on what's not supported by your testing device.Torrid
Not sure if this was ever accurate, but my worker now is doing the work as scheduled even when I don't create any specific conditions/restrictions.Maurizia
I have one situation, App is killed, worker start processing with notification. but due to some exception worker stopped. but notification remain as it is. I want some callback method which guarantee to be called on worker destroy/stopped.Mighell

© 2022 - 2024 — McMap. All rights reserved.