Terminate android service without reset - android

I am aware that force killing an app is very bad, but the client requires it. I am required to implement a force reboot of sorts for the app. This is how I implemented it:
I create a BroadcastReceiver in my Application's (not Activity's) onCreate method. I have it wait for the REBOOT command to be broadcast. Upon receipt, I have it broadcast another message that has the services call stopSelf so that threads and services have a chance to exit cleanly. I then have an AlarmManager call my main activity 5 seconds later. Finally have my application kill itself with Process.kill(Process.myPid()). For the most part, it works, and I just need to add some extra waiting time before it kills the process (maybe by waiting for a TERMINATE broadcast from each running Service). My issue is this: while reviewing the logs, I found out that the system schedules the services to reboot. I'm worried about conflicts. Is there a way to terminate the services without any chance of it rebooting?

I fixed this by having the Receiver wait for all the services to finish their onDestroy() calls before having it die. I also changed from Process.kill() to ActivityManager.killBackgroundProcesses().
As a side note: I know it's wrong, but it really does feel cool killing the processes hehehe.

Related

Starting more than one Service in foreground

I have some android Services in my project. Considering that I did't configure anyone to work in a different processes, what happens if I try to run two or more services in foreground mode? I'll try to explain better my doubt.
If all the Services are in the same process, maybe should be enough starting just one of them in foreground, and then every Service will not be killable, because the entire process should stay alive. Because, actually the process will be considered a Foreground process since, as explained here, it has the following condition:
It hosts a Service that's running "in the foreground"—the service has
called startForeground().
So basically the question is:
Does the start of a service in foreground guarantee that all the services in the same process will not be killed?

onDestroy in Android service

I have a long running service which responds to multiple BroadcastReceivers (created in code, not manifest). Most of the time the service is running well, but from time to time it gets somehow stopped (the BroadcastReceivers stop to work) - I guess the system pauses it somehow (when I look into the running processes on the device I can clearly see the service is still "runnning").
I don't know the right reason why the service is being paused, but I'd like to know whether in these cases the onDestroy() method is called or whether there's a chance to handle this somehow.
I presume onDestroy() is not being called, because the service is still visible in the Running processes tab. I also have the service return the START_STICKY flag so the system should restart it whenever it's killed for memory reasons. Also if it is "paused" somehow, is it possible to create a WakeLock for this not to occur?
I know that the best solution would be to put all the BroadcastReceivers into the manifest and create a one shot-service called from their onReceive() methods. However I have chosen to go with the way of long running service because the initialization stage is very intensive it's better to initialize everything just once.
onDestroy() will be called only when service is being killed by lack of resources or when you explicitly stop it.
The service can be "paused" when your phone goes idle (usually when screen is off) because the CPU stops. To make services run always you should use PowerManager.PARTIAL_WAKE_LOCK - but use it wisely because it does not stop your CPU and thus draining the battery. You should never leave your apps running always. Just do what you need holding a WakeLock and then release it.
http://developer.android.com/reference/android/os/PowerManager.html
http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
You can use AlarmManager to "wake" your apps periodically and do something.
http://developer.android.com/reference/android/app/AlarmManager.html

Prioritize scheduling restart of crashed android service

By using START_STICKY , if my service is crashed/killed by task manager, it automatically restarts. I see that there are a list of services which gets restarted but in a different order. I want to prioritize this restarting of the service so that it will start sooner by placing to the front of the queue.
It typically takes 15 seconds to 45 seconds to re-start the service. Is there a way to prioritize or start this service sooner than the other.
Is your service long running? If it is, try to get rid of it and only start it when it is needed. Android services are not meant to run as a daemon, they are meant to run as short living workers in the background when no user interaction and interface is needed.
Most of the "I'm just sitting around" services can listen to broadcast intents and be a nice citizen this way.
Another thing: If your service is already short running and the a task killer is active, it's easy: It's the users problem and not your fault. The system doesn't need task killers and you shouldn't take care of them. The user should know that it's not healthy to use them.
I guess this solution is a little bit dirty, but you could use a new Service that starts with START_STICKY and set all other services to START_NOT_STICKY.
You could then use the new service to start all other services (though this is not necessarily needed). This is actually an easy implementation, as you can pass the whole intent to the service that shall be started.
Then you could add a Broadcast on all service's OnDestroy() to tell the new service, that one of the old was killed by the system. You can also pass the old starting intent via OnDestroy(), so it gets restarted.
In case your new service gets killed, you can check after restarting if any of the other services was killed, too and then prioritize the restarting.

What happens to a service started by BOOT_COMPLETE after system kills it?

What happens to a service started by BOOT_COMPLETE after system kills it for memory?
Will it ever be restarted without rebooting the phone? Is it possible to restart it somehow?
What is the best practice to avoid as much as possible an important service from being killed?
Will it ever be restarted without rebooting the phone?
Possibly. If it truly was because "system kills it for memory", and you return an appropriate value from onStartCommand() (e.g., START_STICKY), it should be restarted at some point in the future. If the service was killed due to user action (e.g., Force Stop in the Manage Services screen in Settings), it will not be restarted.
What is the best practice to avoid as much as possible an important service from being killed?
First, design your application to not rely on an everlasting service like this. 99.44% of Android applications do not need a service that runs continuously, let alone one that starts doing so at boot time. Android device users hate developers who think that their apps are sooooooooooooo important that they have services running all the time -- that's why we have task killers, Force Stop, and Android killing services due to old age. For example, if you are checking for new email every 15 minutes, use AlarmManager and an IntentService, not a service that runs forever.
If you can demonstrate -- to me and to your users -- that yours is among the 0.56% of applications that really do need a service that starts at boot time and runs forever, you can use startForeground(). This will indicate to the OS that your service is part of the foreground user experience. You will have to display a Notification, ideally to allow the user to shut down your service cleanly if and when the user no longer feels that it is justified.
If you need to restart the service then you should use AlarmManager to check up on the service in a separate BroadcastReceiver, but nominally when a service is killed by the system for memory it will not get automatically restarted.
You may want to take a look at START_STICKY
Use the AlarmManager to periodically send an Intent-- receive the intent and make sure your service is running.

Why does my service get instantiated multiple times?

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.

Categories

Resources