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.
Related
I have been searching the net for hours. I am trying to make an application that has a UI interface and a service running in the background for SIP phone communication, kind of like Skype.
The UI starts and stops the service based on UI events, and the service stays logged in with a internet server in the background. I have found many articles talking about running the service on a separate thread(done), using startService as opposed to binding the service(done) but whenever I use the task manager to kill the application as a user might, I get an error popup saying my application has crashed and the service no longer runs.
How do programs like Skype, Facebook, or email clients do this?
Do I have to run these as separate applications using implicit intents?
Is there some settings I have to set in the manifest file other than declaring the service and it's name?
Better yet, is there a link to some page or source example using this kind of service?
EDIT: Sorry, I guess I wasn't clear. The service is stopping, and I don't want it to. I am trying to keep the service running in the background even after a user kills the application with the application manager.
One of the more confusing things with Service is that it is not run in a separate thread by default. Calling startService() as opposed to bindService() makes no difference in this regard. However, the binder mechanism will cause the Service exposed methods to be called in arbitrary thread context. In both cases, your Service is part of your application's process. If you kill it via the task manager or it crashes then the Service dies as well.
When you kill the app via the task manager and it pops up the message about the app dying, you have something misbehaving. Check logcat and it will point you at exactly where the crash happened.
If you need to have your Service running regardless of the UI, then don't stop the Service when your UI exits. You will still call startService() when your UI starts to re-connect (and possibly re-start it), but don't stop it unless you really want it stopped. Starts do not "stack". If something calls start 5x it doesn't take 5 stops to terminate the Service, only 1.
Anywhere I've looked for this topic says (resuming): "call finish() on your activity and if you have any services running, call stopService() on them".
So that I did, and as it seemed to work, I stopped worrying. Today, debugging a part of my code, I needed to add a Log line into a non-ending thread's method which I want to be executed all the app's life, basically it's something like this:
final Thread buf_liberator = new Thread(
new Runnable() {
public void run() {
while (true) {
methodCall();
SystemClock.sleep(9000);
}
}
}
);
buf_liberator.setPriority(7);
buf_liberator.start();
In methodCall() I put the Log line, and for my surprise, after I closed my app pushing the Exit button which calls finish() and stops a service I've started, I still see the Log message every 9 seconds indefinitely in the LogCat.
So the question(s) is(are): This thread is not a service, why it keeps running? Am I doing something wrong? Is this an expected behavior? Is there a real method to destroy everything the app had in memory?
Thanks!
So the question(s) is(are): This thread is not a service, why it keeps running?
Because your process is still running. Even when you finish() an Activity or stop() a Service, your application process may keep running.
Am I doing something wrong?
Besides creating a never-ending thread? No.
Is this an expected behavior?
Yes. The Android system keeps process around as a caching mechanism to speed up resuming previously used apps. The system will eventually kill your process (and the running thread) as it deems necessary. Do not count on your thread not ending, because it will, eventually
Is there a real method to destroy everything the app had in memory?
There are ways, like System.exit(), but it's generally advised that you let the system work as intended.
Further Reading:
http://developer.android.com/guide/components/processes-and-threads.html
You don't need to worry about this. There is no such thing as "exit application" in Android. When application is launched, Android spawns a process where your application "lives". When your application starts an Android component (like an Activity or a Service), then Android knows your application is active, and it will try to keep it in memory then. If you close all activities and all services, your application's importance gets low. Since now, if Android needs more memory, it will kill the process hosting your application at any time.
In your case, you closed all components, but kept a thread running. It has continued to run in background because Android didn't need more memory and your app stayed "cached" for possible future use. If you had started a memory consuming game then your app would have been killed. So you cannot rely on the thread running outside of an active component (like a service) as it can be killed at any time.
If you really want to exit the app, you can try to call standard Java function System.exit(0). This is not necessarily needed, but you can use it if you want to.
I have started a service from my application and from that service a worker thread is started .I want my service to run even application goes background and until the user kills/exits the application.
But some cases my service got killed due to low memory ,then used sticky service or making the app to foreground to restart the service.
My issue is I dont want to lose the data between service ending and restarting time ,so is it possible to start another thread from service ondestroy method, but in this case how we can control that thread.
Please let me know is it the right approach ,and is this usecase achievable
I want my service to run even application goes background and until the user kills/exits the application.
This is not possible. The user can always get rid of your app, via Force Close in Settings, or via some device's version of the recent-tasks list.
But some cases my service got killed due to low memory
No, your process is terminated for low memory.
My issue is I dont want to lose the data between service ending and restarting time ,so is it possible to start another thread from service ondestroy method
No, because your process is being terminated.
Please let me know is it the right approach
Probably not. Very few apps need a service that runs constantly, which is why Android, and its users, go to great lengths to control such services. I would recommend that you try to find some solution to whatever your problem is that does not need a service running constantly.
I'm write an auto-speaker app which has a service inside, and listen to the phone state change.
I expect that the service should be exist all the time and can't be killed.
However, I found that if I use some task killer to kill my app, there will be few seconds my listener won't work.
Although my app seems to be restart automatically in few seconds later and work again.
Why the service could still be killed by task killer??
Is a service just like an activity, just with no UI, and able to restart automatically?
Thanks for your answer.
You cannot exempt your service from being ended by the user or automatically by the OS when resources are needed for that matter.
The best you could do is attempt to write code to compensate for restarts but certainly don't write as if your service will run forever without exception.
EDIT
Android Developer documentation Managing the Lifecycle of a Service has useful information on recovering from stops and when the callback hooks get called and not.
Add this trick to your service onCreate:
startForeground(R.string.app_name, new Notification());
It will prevent service from closing on low memory, task killing etc..
Because taking away the ability of the user to end a process when he/she wants to is just wrong. Instead try to write a work-around so in the event of of the service shutting down, XXXXXX takes place.
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.