I have a content observer detecting onChange successfully when the application is running in the foreground. I want to kill my application (swipe it away) but still have this content observer be able to detect onChange. I have tried many many things, but need help achieving the dream scenario.
Start a foreground service (which forces a permanent notification), and registers the content observer in the foreground service. This method "works" but I really hate that permanent notification. My app currently work this way and I get complaints about the notification, thus my motivation to find a better method.
Start a background service, keep it sticky. This does not work, because in newer version of Android, even sticky services gets killed after your main app gets killed
Start a background service, on its onDestroy() method, send broadcast to restart the service. Basically read this guide. This doesn't really work either, my service restarts a couple of times, then I get errors which basically says I am trying to restart my service too many times.
Start a background service, which starts a thread that runs forever. In the thread, do the content observer. I haven't tested this method yet, but it seem really bad because It will probably create orphaned threads, just seems really bad coding practice. Has anything tried something similar?
So basically the issue newer and newer Android is recycling services in almost all situations. How do I keep a background service running forever, because I need a content observer to run forever and listen to changes.
Other posts which i have read are this, this, this, this
Related
I have been trying to get an Android service to take pictures in the background using the action.USER_PRESENT trigger. Suprisingly enough, it works.
I am confused about the mechanisms involved however. Going to list some points below, please correct where I am wrong.
When an intent filter is registered in the BroadCastRecevier via manifest, it will be triggerred even if the app is closed, correct?
The created service runs its methods on a newly created thread, and will execute until end, no matter what.
What are the mechanistic differences in how the service behaves when the app is open, in the background (or stopped in some devices), or destroyed?
action.USER_PRESENT triggers when the user passes his lockscreen?
In addition, I would invite suggestions to alternative triggers to USER_PRESENT, when my condition is that the service be triggered whenever the user is using his device.
When an intent filter is registered in the BroadCastRecevier via manifest, it will be triggerred even if the app is closed, correct?
Android developers do not use "app is closed", as that is not a specific description. Many things might qualify as "app is closed". In this particular case, your receiver will work even if your process is terminated, which is my guess for what you mean by "app is closed".
The created service runs its methods on a newly created thread, and will execute until end, no matter what.
No.
First, in Java, objects do not run on threads. Methods run on threads.
Second, there is no requirement that any work done by a service "will execute until end".
All a service means is that you are telling the OS that you are doing work that is not tied to the foreground UI, and that will hint to the OS to try to keep your process around a little bit longer. How long "a little bit longer" is depends on Android OS version, system RAM, what the other apps on the device are doing, etc.
What are the mechanistic differences in how the service behaves when the app is open, in the background (or stopped in some devices), or destroyed?
Apps are not "destroyed". An app's process being terminated is the closest thing that I can think of to what you might mean.
Once an app's process is terminated, all running code is gone, including any running service code.
There is no difference in the behavior of the service itself whether the app has foreground UI or not. Having foreground UI means that the app's process is very unlikely to be terminated, assuming that your code does not crash.
action.USER_PRESENT triggers when the user passes his lockscreen?
Yes, IIRC.
My app is running an IntentService to download data in the background. While doing so, it sends Notifications to update the user about the progress.
The problem is, if the BatterySafe mode gets started, the IntentService gets killed, the Notifications stay there though (for example saying 30%).
Is there a way, to couple the lifecycle of the notification to the lifecycle of the service?
A second problem is, that I only want one instance of the IntentService. Is it possible, to achieve this?
In some Apps, for example the Avast AntiVirus, the background task seems connected to the notification, indicating that this background task is running. If this is a standard solution, it seems to solve my problem, so it would be great, if you could tell me the name.
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.
my knowledge of services in any operating system, is that they usually run in the background and perform whatever work they have to do.
but the first time I got familiarized with android services, I got confused.
it appears they only run when the application is working, and that for me, makes them no more then sophisticated threads.
do I have this all wrong? how do I make a service that runs when the application doesn't? (so that I can check for updates and create notifications for the user that will then lead him to the application if he chooses to open them).
does push notifications have anything to do with it?
Edit:
thank you guys for your answers so far.
my problem seems to be the fact that the service is only started officialy when the device is booted up. I do call startService when the app starts, but that doesn't seem to help. the service still dies when the app is turned off (unless it was booted)
also I never call stopService
If you are trying to implement a long running task that is performed in a (background) service, you have to start one or more threads within your service. So the service just gives you the opportunity to have an application context without having to have a user interface ;) you can consider it as a kind of container.
This page give you a nice overview about different thread approaches in Android. As you can see a service has not its own thread.
Anyway, in your case it seems that an AlarmManager is probably the better option. Running services for polling information all the time can be quite CPU and battery consuming (see this post for instance). So try to avoid having threads that run all the time.
If you can push information about updates from a server it's just fine. Check out Googles Cloud Messaging in this case.
Michael who commented on my question first was right in his comment about startService()
so it goes like this:
my receiver is only activated on boot, and uses an AlarmManager to
time the service to certain intervals.
what I did was to bind the activities to the service. if the service
was off and I binded it and unbinded it, then by the time the app was
terminated, there was nothing keeping it alive.
by simply making sure that the service was started properly with
startService if it is not already on, I managed to keep the service
alive at all times
also thanks to Trinimon who gave a very nice explanation on what
services are, and the importance of not overloading the CPU with
excessive polling. (which is kind of a trade off situation)
good luck to all :)
IIUC, there should only be one instance of a given Android service, it is a singleton.
However, my service gets instantiated multiple times, although I
do nothing for it.
When the service crashes (for example when I uninstall the app through adb), it
gets scheduled for restart ("Scheduling restart of crashed service.. "). I
understand this is an effect of the service being sticky.
After that, when my app starts, it calls startService() and bindService(), and
the service gets appropriately started and bound. But the service is then
reinstantiated and onCreate() is called repeatedly, as many times it was
scheduled for restart.
Each instance then wait for clients to bind and register, but onBind() is only
called in the "main" service instance. The additional instances wait a bit for
client to bind, and since that doesn't happen, they call stopSelf().
But stopSelf() has absolutely no effect in these "dead" instances, onDestroy()
is never called.
The "main" service instance does work as expected, and when it decides to call
stopSelf(), onDestroy() is indeed called.
Worse, all these dead instances accumulate, they never gets destroyed.
Therefore, their only possible end is a crash (which happen every time I
launch/install through adb), and thus scheduled restart.
So that in the end I get many of these dead instances, which are restarted
progressively once by minute approximately.
Does anyone know what's going on?
I got similar behavior if I use eclipse to restart an app with a remote service. According to logcat, system consider the killed service had a crash and tried to restart the service. At the same time, the service has been restarted with the restarted app. For some unknown reason, Android system does not realize there is already a running service, and tries to start a new one.
It happens several times on Optimus one, Galaxy tab, and EVO 3D. It is fine with Nexus one.
Because I haven't seen your code, this is just a guess: Maybe you have a memory leak that prevents the service from destroying properly. That's the only reason I could think of to get multiple instances of service. For example, if you service is holding on to some object that also have a reference to your service. It happens a lot with inner classes.
Check out this video from Google I/O to see if this problem applies to your services and how to find it: http://www.youtube.com/watch?v=_CruQY55HOk&feature=player_embedded
if you use the section to be excecuted in onstart() . if ur starting the service by onclick button or like clicking on icon multiple time means ,what it will do is if service is already running means ,it will go to onstart(),so the method is excecuting again and again its not that service is starting multiple times .... ur method is running for multiple time ,This i told accornding to my guess may be exact code will be Explaind properlly
if your app exit on crash or kill the process it belongs to like System.exit(), it will start after your app exit or start if your service is running in the same process with Application.
Because you kill the process, and Android detect your service should not stop, so Android restart it for you after your app exit. And why service start again after app restart, I think it is Android's bug, it reallocate a new process to your app instead of using the process allocate to your service.
So, how to solve this problem?
just set the attribute android:process=":background"(whatever you want here, starts with :) to your service node in AndroidManifest.xml. hope it helps you.