I'm writing an Android application that records video and then runs post processing on recorded video. Since post processing may take a while (up to an hour) I'm scheduling a service - JobService using JobScheduler to run when the phone is connected to power and idle i.e. to run at night.
The job service doing the long-running job on a new thread.
In practice my scheduled service is working VERY slow. It seems that although it runs when system is idle, it gets very little CPU bandwidth. Also my service is being stopped after 10 minutes max by the OS.
I know Android Oreo limits background processing. This is well documented by Google. However I'm wondering if there is a way to run background services when system is idle.
Is there a way to run long background services when system is idle? For example video post processing?
You need to use a Foreground service.
They are one of the few methods left to run long background tasks. The user must know what's happening on his device and he should have the ability to decide to stop it or not.
You can read how to implement basic Foreground Services here, and there are a lot of guides on the internet on how to implement them in an advanced manner.
Remember that even a Foreground Service can be stopped by the OS if the system is in extreme memory pressure and the only things left to destroy are foreground services. So you should always have a recovery procedure if that happens.
Related
In my app I want to show notification on exact time when the app is working in background or even it is closed. I used AlarmManager and service with BroadcastReceiver to show notification. The latest versions of android doesn't allow to run service in background after app closed and foreground service is consuming battery, slowing down the device etc.. I wonder if I could use something else can work even app is closed and show the notifications. I've heard of WorkManager and JobScheduler for that kind of operations but can they do the work even if app is closed?
Foreground services is not consuming more battery and not slowing down device, just notification is shown.
And the answer is basically it is not possible to make continuous background service on new android API's. You only can schedule tasks with tools like WorkManager, JobScheduler and so on.
These days I think WorkManager is the answer because Android team is focused on it this year.
Also even continuous foreground services gets killed after some time.... To avoid that 2 things has to be done:
Native battery optimization for app should be disabled.
Phone manufacturer (another battery optimization) has to be also disabled for specific app.....
I know it is worst user experience, and they throwing away half smart things that phone can do, but life is life :)
I have been reading lately about how background jobs are done in Android (using Service, AlarmManager, JobScheduler, etc) and learned that these background task can go indefinitely even the app has already closed or device has screened off. I understand that the only they stop if they stop themselves or other components stop them.
Questions:
If I have a background job or an alarm that goes every 1 hour. Does it really runs forever until a component stop them? Is there an instance that the system will stop them?
What if I have periodic job or alarm that goes every 1 hour. Will they stop if I uninstall the app that started them? Cos I never read this part in any documentation.
Is there a way to check any running or pending background jobs/alarms in my device?
The explanation that is given about background tasks in your question only applies to Background Services, that to only in Android API Levels below 26.
Google recommends using JobScheduler or Foreground Service to do some work in background even when app is not in foreground.
Coming to you questions
No, If your using JobScheduler or Alarm manager the system will trigger your job to do your work depending on device idleness and conditions mentioned by you but the system can anytime come and stop your work in between when the conditions are no longer met.
If your are using JobScheduler it will inform you when system wants to stop by force so that you can handle it properly and reschedule if needed
When the App is uninstalled every job or alarm that is scheduled or in-Progress will be destroyed.
Yes, JobScheduler does provide a function 'getAllPendingJobs'
Note :
For works that should be scheduled or completed even when app is closed then try avoiding the use of Background Services or Alarm Managers.
JobScheduler is much more better replacement.
If you want to do some simple background work when the app is in foreground then try using HandlerThreads or AsyncTasks
I have read many posts state that doze mode killed a running service at a particular moment e.x link or that they want to execute a long running thread.
I can't understand why you should use a service to do a background job that you know that in some point it will stop eventually.
For instance:
You could use a simple Thread:
new Thread(new Runnable).start()
and do some work in it. Using this:
In combination with a wake lock, device wont sleep and thread will keep running.
No doze mode restriction (except network but lets say we do local stuff)
So you can do background work with no restriction whatsoever. Although you should use services for these reasons link.
Is this another way (not better of course but a way nonetheless) of doing a background work? Am I wrong?
There are a lot of ways to do a background job aside of services check this link it may help you pick the best option for your work :
Job Scheduler vs Background Service
And services as #TheWanderer said will continue to work event after the app is closed for a period of time unlike a simple thread that will end immediately when the app is closed.
Read this part in the link that you linked
Services are given higher priority than other Background processes and
hence it’s less likely that Android will terminate it. Although it can
be configured to restart once there is ample resources available
again. You should go through the different processes and their
priority/important level in the documentation on processes and
threads. Assigning them the same priority as foreground activities is
definitely possible in which case it’ll need to have a visible
notification active (generally used for Services playing music).
If you are running a background thread that you start from an Activity, Android does not know that you are doing background work in the OS Process that is hosting your Activity. Android can kill the OS Process hosting your Activity at pretty much any time. If the user presses the HOME button or takes a phone call or opens a notification and goes to another application, Android can kill off the OS Process at any time. When the user returns to your application, Android will create a new OS Process and recreate all the relevant activities, but your background thread is hopelessly lost. This is the reason that Android has services.
If you start a Service to perform your background processing, the Service will also start background threads, but these are controlled. Your Service tells Android what to do if it kills the Service while it is processing an Intent. Your Service can therefore be informed and restart (or continue) the background processing as necessary. You can also run the Service in a different OS Process from the OS Process running your activities. This will prevent Android from killing the Service if the user removes your app from the list of recent tasks.
With newer Android SDKs there are other mechanisms you can use, like JobScheduler.
My app relies on logging the battery temperature, as well as several other sensor variables, every second in a background service that can be started from the main activity and continues running in the background until it's stopped (by another button in the main activity). This works fine in Android 7.0 and below, but reading into Android 8.0, it looks like it limits background services pretty severely. Can I still do this data logging that I currently do, or is that no longer possible?
If your usecase is to keep the app in foreground during this processing then,
based on the documentation, there shouldn't be any problem, since the restrictions for background service is applied if your app is not in Foreground or no foreground app is connected to the app
X minutes (based on my observations its around 1 - 2 minutes) after your app enters in background all the restrictions for background service will kick in and your Service will be stopped as if you have called Service.stopSelf()
You should avoid doing it continuously, since it will impact battery life of the device, if are intending to do in background. You can perform logging periodically using JobScheduler/AlarmManager.
If you still want to proceed, you can make the service ForegroudService and perform the operation but if system considers your task as CPU intensive then this approach wont' work either
I am working on an Android project and I need the app to work even when the device is locked.
The idea is to open the app that will start the (Intent)Service, the service processes the data all the time. The device can be locked/put away and after some time when the app is opened the service is manually stopped. The service should be running all the time in the background.
I have found information online, but I am not sure what to use and in which way..
I have found that the IntentService can be used. Also the service should run in a new thread. I need to process the data from gps all the time, should I use WakefulBroadcastReceiver?
Thank you.
IntentService is not necessarily what you want to use. It will automatically spawn a new thread just to handle an incoming Intent. Once all incoming Intents have been handled it will stop the Service. To have a long running Service, you would need to derive from Service and when it is started return START_STICKY from the onStartCommand() method, plus spawn your own thread to handle your background work.
If you need to monitor GPS, you'll have to manage that along with keeping the device awake using a WakeLock. Note that in Marshmallow, this gets more complicated because of the new Doze mode where even wakelocks are ignored.
Also, note that the way Android is architected there is still a chance that your application running the background Service may be killed. Android uses a unique process management technique based on memory pressure and user perceived priority to determine how long a process should stick around. I recommend reading up on the Service lifecycle in the documentation.
In android their is no fool proof way to ensure that your service runs forever because the LMK(low memory killer) when the system needs resources (based on a certain memory threshold) , kills the service then if it can restarts it. If you handle the restart properly the service will continue to run.
Services that are given foreground priority are significantly less likely to be killed off, so this might be your best bet. However their will be a notification of your service running the in the background on the menu bar up top. Foreground Service