I finished an Android program. It uses thread. No service.
I would like when the user closes the program with the BACK button
to give an option for the program to keep working in the back ground, or part of it.
The question is what is the best way to take and how to implement it.Is SERVICE the only
way to go or there is another way?
I have seen tracking programs do it.
Yes , service is the best choice of all to keep your application running in the background.
But also remember that keeping a service running does not mean its guaranteed to not getting killed.If resources are too low, Android system might kill your service too.
Please go through this and check Process lifecycle under it.
As you know ,phones are very limited in the amount of resources, its ideal that you do minimum amount of work in the background and also if you require to download something in the background after a specific time consider using AlarmManager instead of polling in the service.One purpose of creating a thread is not blocking the UI.Remember that a Service runs in the UI thread itself,So starting a thread inside a service is a better choice if you want to have long running background work.
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.
I have a long running background task that I would like to start when the app launches and shutdown when the application shuts down. I'm already quite aware of the activity life cycle and what gets called when an activity gets created and destroyed.
I'm coming from an iOS background, and over there we have some calls that are made during application startup and shutdown. Is there something similar in the android world? I've searched a lot and all I'm finding are answers relating to an activity, not the entire application.
(Android is relatively new to me, so I may just not know the correct terminology to search for.)
EDIT:
I'll try an be a bit more specific. I have a background task that needs to be continuously running while the user is using the application. It will be streaming data from a server continuously while the application is active. It does not need to run when the application is in the background. It doesn't seem to make sense to me to tie the startup / shutdown of this background process to any one single activity since it may not be the same one activity that starts up when the application becomes active.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses. If that is, in fact, the case, then all I really need to do is spin up the background task when the application first launches, i.e. when it is loaded into memory and becomes active for the first time that session.
It doesn't seem to make sense to me to tie the startup / shutdown of this background task to any one single activity since it may not be the same one activity that starts up when the application becomes active.
That's reasonable. It is somewhat difficult to implement, though.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses.
You have it exactly backwards. Android pays not one whit of attention to any threads that you fork yourself, directly or via thin wrappers like AsyncTask.
In addition to that point of confusion, you appear to be equating "user switching to another app" with "app shutdown". Those may be the same thing in single-tasking operating systems. They are not the same thing in Windows, OS X, Linux, Android, etc.
So, what you seem to be seeking is having a background thread running doing this streaming work while your UI is in the foreground, and then stop when your UI is in the background. The problem is that there really isn't a straightforward way of accomplishing that in Android.
One close approximation would be to create and register a custom Application class, where you override onTrimMemory(), and stop your background work when you get to TRIM_MEMORY_UI_HIDDEN, TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE, or TRIM_MEMORY_COMPLETE -- whichever of those that you encounter first. If, when one of those arrives, you determine that your streaming thread is still outstanding, shut it down.
In terms of startup, you could use onCreate() on that same Application singleton. The problem is that this will be called on any process creation, which may include scenarios in which you do not have UI (e.g., you are responding to some system broadcast, like ACTION_BOOT_COMPLETED), or possibly your process is going to parts of your UI that do not depend on the streaming. If you have none of those scenarios, then onCreate() in Application would be fine. Otherwise, kick off the streaming in onCreate() of whatever activities need it.
While normally we manage long-running threads with a Service, that is for cases where we explicitly want the thread to continue after our UI is in the background. Since you do not want that, you could skip the service.
It depends on what you want to do exactly. When you're just interested in the app starting for the first time you could #Override onCreate().
Or maybe you want to use onResume() as this will get called whenever a user brings the app to the foreground.
But this really depends on what exactly your background task is doing and what you want to do with it, to get an exact answer you need to provide more details.
Here is an overview for the actiity life cycle that should help you:
You can extend the default Application class and implement it's onCreate() method to detect when the app is launched. There is no corresponding method for when the app gets closed though.
Do not forget to specify it in the Manifest file.
In Android the application isn't shut down unless the system runs low on memory. You won't get a warning about that, it will just call your Service's onDestroy lifecycle method. If you want to do it when the Activity is visible on screen, use onStart and onStop. If you want to do it when the Activity is resident in memory, use onCreate and onDestroy.
When you learn to develop for Android, you learn that if there's any type of process -that takes more that 5 seconds- running inside the ui thread, the system will show the infamous ANR message. That's when they introduce the evil monster... AsyncTask. At first you see this class as your savior, but then you realize it's the biggest problem in development... Handling rotation or ui events becomes so problematic, it's even painful.
What do you guys think about it... are AsyncTasks worth the trouble? Any other method that makes it less of a problem to perform long running tasks regardless of screen rotation?
I guess you'll probably say, hey why don't you just make it a Service... Yeah that's a solution, but then let's go to my real question. Why don't we just use services and stop using AsyncTasks completely... Are they useful at all?
While developing it is always good to choose the suitable component for the execution. You need to clear your requirement and according to it you can choose between a Service or an AsyncTask.
A service is an Android component that lives independently from any other components. Activities may come and go, but services can stick around, if you wish. They serve a number of roles, from managing state that multiple activities rely upon to serving as cron jobs to handling longer app widget updates.
AsyncTask is a class that arranges to do some work off the main application thread. From the implementer and user of the AsyncTask, how it performs that bit of magic is not generally important. In reality, it uses a thread pool and work queue. AsyncTask uses a Handler to help arrange for select bits of work to be done on the main application thread (e.g., notifying the user of progress updates).
For more clarification see the difference between them.
AsyncTasks and Services are not peers. Either might invoke the other, their purposes are different. I have just a few things to add to Lucifer's answer.
A key thing to remember is that if your process is in the background, hosts a Service, and is killed, that Service will be reincarnated at some point. This is not the case for an AsyncTask that may be running in a process when it is killed. This means that work being done in a Service is guaranteed to make forward progress in the future (although its not guaranteed when). If you have work that must be done, better to do it in a Service.
Calls to Service.onStart and Service.onStartCommand happen on the process' main thread. If you block this for a long time, you'll get the same "app not responding" dialog. As a result, an AsyncTask can be a great thing to use inside a Service to do the real work.
I tend to use AsyncTasks initiated from an Activity for things related to the UI. These are often things that aren't required work and whose work can be easily redone in the future. For example, this might be reading a bunch of images off disk or make a calling to a web service to see if the user has any notifications. This work can be done again, and if the UI is destroyed because the process is killed the work probably needs to be done again anyway.
If on the other hand you want to say upload a group of photos to the web as soon as possible, I'd farm this out to a Service which will use one or more AsyncTasks to do it. This is work I want to get done and want to be resumed if it gets interrupted. If you're going to use a Service, consider using an IntentService so that your Service stops when its work is done.