I have obtained images from the camera and want to save it to a directory after some processing which takes about 10 seconds. I tried the following methods :
1) Asynctask(Problem : if the user closes(swipes) the app, the asyncTask is killed)
2) Intent Service(Problem : same as Asynctask)
3) Foreground Service(Problem : Hangs the UI of the application)
4) Running on UI Thread(Problem : Hangs the application).
So my question is what should I use to save my images(with some processing) such that all tasks are done even if app is closed and the UI does not hang(freeze).
Any help would be appreciated.
You cannot prevent Android from killing your process. If the user wants it killed (for example, using "force stop"), it will get killed. There is nothing you can do to prevent that.
When the user swipes the task from the recent tasks list, the behaviour is different in different versions of Android (and also different manufacturers have different behavour). However, in most cases, the OS Process hosting your app (including any services) is simply killed. If the app had a running Service that wants to be restarted, Android will create a new OS Process and reinstantiate the Service and restart it.
You can mitigate this a bit by putting your Service in a separate OS process. To do this, add android:process=":remote" to the <service> declaration. On some versions of Android, swiping the task from the recent tasks list will then kill the OS process hosting your activities, but NOT kill the OS process hosting your Service.
In any case you need to make your app robust so that it can handle being killed and restarted.
Thanks everyone for suggestions. How I finally was able to achieve this was using a foreground service which itself created and asynctask to perform the work in the background. I am a novice so don't exactly know how it's working, but it doesn't cause any app freezing/lag and does the work even if the app is swiped from the recent tasks list. (tested in Android L(5.1.1) and M)
Related
The title isn't good, so please read this description to understand what i mean.
I created a background service that i want to run for a long time, by definition services on android can run even if user switch the app or even closes it.
My question is: how does android management system knows which threads to keep and which to wipe when the app goes background and the only running thing is the service?
My service runs by default on the mainthread, so when i want to perform a long task i do:
AsyncTask.THREAD_POOL_EXECUTOR.execute(runnable);
is that right? can i use this default threadpool created by android or the service must explicitly creates the thread in order to the system knows that thread must survive even if the app goes background?
how does android management system knows which threads to keep and which to wipe when the app goes background and the only running thing is the service?
Android does not "wipe" any threads. Android terminates processes to free up system RAM, not threads.
is that right?
I would recommend using your own Executor, RxJava, or Kotlin coroutines, over using the executor in AsyncTask. That is because I expect AsyncTask to be deprecated sometime, as it is "old school".
However, beyond that, what you are doing sounds fine.
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.
Search engines and Android developer website didn't help and I guess you can help with my problem.
I want to make an app for personal use, which is supposed to run all the time on my old tablet (powered all the time). The app will have several features requiring user interaction but independent of those, it should run a background job to check something continuously (real time!) for instance sound detection. It should also always try to connect another device on the network.
That means that job needs to run almost eternally without being killed. Some comments I have found suggested AlarmManager or BroadcastReceiver. But those are triggered by very defined triggers (either time or broadcast). I don't want that, because it should perform its task continuously all the time. This background job should also be able to communicate with the main Activity of my app to report what it is doing and allow user to interact with it (change settings of the job for instance).
Do you know any way how to accomplish this? Is IntentService correct choice for this (hoping that it won't get killed or maybe I should let the Activity to restart it?)
Thanks!
Do you know any way how to accomplish this?
Build your own custom ROM, with a modified version of Android that contains your code as a native Linux daemon.
Otherwise, what you want is technically impossible.
You can come fairly close by using a foreground Service (not an IntentService) and returning START_STICKY or START_REDELIVER_INTENT from onStartCommand(). Android may terminate your process from time to time, but it should restart your service automatically after a short while. That service can use its own background threads to do whatever it is that you are trying to do.
In the app I'm developing atm. I use asynctasks to upload videos to a website, as it stands now if the application process is killed (User returning to home screen using the back key), those asynctasks are lost. ideally I would want the uploads to carry on despite the application process being killed, but I don't think that is possible.
I wonder if there is a way to retain their progress somehow (Maybe support from the website API is necessary?), or if not at least save the details of the asynctask and restart it when the app is opened again.
Vimeos application seems to have been able to resume video uploads, even after having killed the application process, thats exactly what I'm hoping to achieve.
Appreciate any ideas and suggestions.
I think you may be using the wrong architecture.
Anything that needs to survive in between Activity transitions is more suited for a Service. A service runs in the background (possibly even after the app is closed) and lets you do long running things such as performing uploads.
To kill the app process but have the Service continue to run, you can assign the service to a separate Android process using android:process in the manifest.
http://developer.android.com/guide/topics/manifest/service-element.html#proc
See this thread too:
How to keep a service running in background even after user quits the app?
My situation:
I have created an Android service, which is started when the app is started. The service consists of a simple Thread that waits for 5 seconds, writes a log message and waits again.
After closing the application (using the back button), Android chooses to restart my service , because I am returning START_STICKY in OnStartCommand.
When debugging the application, I can actually use DDMS to kill the process. Android again chooses to restart the service. This is expected as per the manual.
I also installed a task manager, and used that to "kill" the instance. Funky thing, is that now my service is no longer restarted.
The funky thing is this: in either case, no destroy code of my classes is called. No InterruptedException is raised on my waiting threads. There seems to be no way for my application to know it's being destroyed.
My question:
How can I get around this, and respond to kill requests? I already noticed that the DVM lacks sun.misc.Signal and sun.misc.SignalHandler for proper signal handling (if that's even being used by task killers).
I kind of need to know wether my app is being destroyed, so I can properly close file handles, database connections and the likes.
Many thanks for any assistance.
How can I get around this, and respond to kill requests?
You don't. OTOH, this task killer behavior should have been eliminated in Android 2.2, so it eventually will not be a problem.