I'm trying to implement a service relationship that roughly looks like this:
{ACTIVITY} -> {SERVICE1} -> {SERVICE2}
The ACTIVITY starts SERVICE1 which then starts SERVICE2. It is very very important that SERVICE2 can shut itself down. If SERVICE1 crashes, SERVICE2 should have a chance to shut itself down cleanly. I've already achieved that using a remote process for SERVICE2 so if SERVICE1 crashes it can shut itself down.
The tricky part is if the user does a Force Close through the application manager.
I understand that no solution is 100%. BUT! I've noticed that the Yahoo Weather app is able to run something they're calling a "Watchdog" in a completely separate app line. Killing the main Yahoo weather app doesn't kill the Watchdog app. WHAT VOODOO IS THIS? And how can I replicate something similar?
Images of the yahoo app:
https://dl.dropboxusercontent.com/u/2193687/device-2014-05-22-151216.png
https://dl.dropboxusercontent.com/u/2193687/device-2014-05-22-151236.png
(converting conversation in the comments to an answer)
Background
Typically a "watchdog service" would refer to a service running in a separate process that would try to restart some other target service if it crashes, or if the user force closes it.
Another similar trick would be to register with the AlarmManager to broadcast a periodic intent that would restart your app / service.
Somewhere along the way (HoneyComb I think), Android changed their security model. Apps could be marked as "bad" by the system, which would not launch them again until the user manually launched them. An app became "bad" if it crashed too often, or the user force closed it.
This includes apps that receive the ON_BOOT_COMPLETED intent - they will not restart if they have been marked bad like this.
So the "watchdog" stopped being as useful (some may say annoying, or battery draining) as it used to be. It might still be useful for an app that has an occasional crash
Remote Process
I initially recommended a remote process as the best way to accomplish this. I then saw that you had already done this, and it works.
Unfortunately this will still not be able to restart the service if it has been stopped manually. It doesn't seem like Yahoo's WeatherServiceWatchdog is able to restart the main Weather service either.
Related
I tried to find if there's a way to run foreground service (one which would hopefully never be killed) without any ui. (Ok I guess notification is necessary but other than that)
This is a very specific use-case since the device being used is a custom one (not a phone), where we need one 'server' app, and might be couple 'client' apps. Clients app will have all necessary ui, but server app should behave in a way like a web server.
I understand this is not a intention of foreground services, but it is justified in the use-case we have.
Bonus question: Is there a 'best' way to achieve an android process/service absolutely constantly running and never being killed by platform for cleaning the memory, since this service will be de facto critical part of the system. Like a phone/dial app on phones for example
Sorry, I can't write comments so I have to post an answer.
It's not exactly what you are looking for, but maybe this google codelab can help you
start with something:
https://codelabs.developers.google.com/codelabs/while-in-use-location/#0
The code in the sample project starts a foreground service whenever the app leaves foreground, allowing the service to "survive" even if the application it's destroyed. Basically the system will not stop the service because tied to his notification.
Plus the service can be stopped from the notification itself.
Maybe with a foreground service started from a device boot broadcast you can have an "always running service"
I have android application with several services.
This application should send reports to remote server when this application has been started and when has been stopped.
But I don't know how to determine that application was stopped, because application may be stopped (crushed for example), but services still running.
I think that the algorithm should be like this:
Check the mark with last date from storage (and if this mark exists - send "stop" time to the server)
Send "start" message to the server, when application was started
Every 10 minutes application should writes current date and time mark on disk
If I will create service with this check - android can kill this single service when there is low memory, but application can be running. If I will create ScheduledExecutorService in Application class - application can stop, but services can be still running.
Can you help me with solution?
There's really not a single answer to this question. It has been asked many, many times here at SO, but all we can say is it really depends on our app's behavior.
You want to put some Log messages in onPause(), onStop(), onDestroy() in your Activity, and onDestroy() in your Service. Watch the the flow of the app carefully by looking at the Log printed out in the Logcat.
Lots of people try to rely on onDestroy() method because it looks like it is called when the app is completely terminated, but that's not always the case. Sometimes app crashes (force closes) or some people just manually force close it in the app information in settings. In that case, app does not follow the lifecycle of the activities.
One of the suggestions would be creating a thread that runs in background and send a UDP packet to a server saying that the app is alive in every few seconds.
PRO: You don't need to make a handshake with the server so it saves time/resources getting response back from the server.
CON: Thread running background does use battery. UDP can be only used in WiFi environment for recent Android OS.
Hope you find a good way. You may want to comment to your post when you found a good solution, because people would like to know how to solve it, too.
Why not try to trust standard methods Activity?
You should approach onDestroy and / or onPause. It depends on your logic.
In addition, you can try to override Application.onTerminate(). You can read about it (Application) lifecycle here.
I created an Android app and need to make it difficult for users to stop the main service that the app spawns during its startup process. This is for a rooted Jelly Bean 4.1.2 device. Here are some steps I've taken so far:
Installed as System App
Uses the Device Admin APIs
android:allowClearUserData="false" is included in the AndroidManifest.
The steps I've taken so far takes care of most normal ways a user would stop/disable an app/process; however, when you check the running apps list in Settings -> Application manager -> Running, users can still hit the 'Stop' button on the long-running service that was started by the app (see picture below):
Is there any way to prevent users from stopping the service here? Or what's the best way to restart a service when a user hits this stop button? I tried putting some code in the service's onDisable() function, but that function does not seem to be called in this case.
Any help would be appreciated!
As explained above does not have this option unless it is executed as root, but you can create an AlarmManager when starting your service that runs from time to time, the system will run if the service is not running, it will be created again.
Is there any way to prevent users from stopping the service here?
Having your app be a device administrator probably blocks this. It definitely blocks the "Force Stop" option.
I tried putting some code in the service's onDisable() function, but that function does not seem to be called in this case.
Since there is no onDisable() on a Service, this is not surprising.
This is a security app for an enterprise, so its expected to be continuously running.
There is nothing intrinsic to "a security app for an enterprise" that would require it "to be continuously running".
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 :)
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.