When I close the Activity the service is killed then started again - android

I have a simple android program containing one activity and one service.
I am starting the service from the activity by calling: startService()
The service should continue running when I close my activity as I started it by calling startService. What I am noticing is that when I close the activity the service is killed then started again after short time.
Is that a normal behavior in android?
If it is normal, is there any way to enforce keeping the exact service running?
Thank you very much
Rami

How are you "closing" the Activity? There's no need to kill an Activity once you're finished using it, and the Service should keep running even if your Activity is in the background.
Service.onDestroy() is called before the system destroys your Service. However, I am inclined to believe that you have a different problem, since it's unusual for a Service to be killed unless your device is very low on memory.

Related

How is a running IntentService managed after the app process is killed

Just trying to clarify my understanding of how an IntentService is managed by the OS once terminating states have been reached. By terminating, I mean when the current activity is destroyed or the app process is killed, as per the following documentation:
https://developer.android.com/guide/components/activities/activity-lifecycle
Given the comment
Also, an IntentService isn't affected by most user interface lifecycle events, so it continues to run in circumstances that would shut down an AsyncTask
at https://developer.android.com/training/run-background-service/create-service;
I feel as if:
1) A started IntentService is unaffected by the activity lifecycle. Is this correct?
2) If (1) is true, will it continue to run indefinitely even after a terminating state is reached, up to some point that it either stops itself or the OS decides to stop it?
In my particular situation, I'm using an IntentService during app startup to query APIs, grab content, and then add a new (landing) Page to the Xamarin.Forms navigation stack (this would be equivalent to starting a new activity).
This leads me to my next question...
3) What happens if the app is already in a terminated state when it comes time to the IntentService creating a new Activity? Surely the Activity can't be added to the navigation stack as it no longer exists once the app is terminated?
Yes, a started IntentService is unaffected by the Activity Lifecycle. Actually, all Services outside of bound Services are unaffected by the Activity Lifecycle.
An IntentService will continue until it reaches completion of it's work, the application is destroyed, or if the System decides to kill the Service due to the changes in the Android 8.0 background Service rules.
Your use of terminated state is too broad... If the Application is already terminated, then nothing will happen because the IntentService would have been terminated already too. If it's the Activity that launched the IntentService that was terminated, then nothing happens, since by default, an IntentService has nothing to do with Activities, even if it's the one that started it.
For the last question, it really depends on how you choose to communicate the result of IntentService to an Activity.
If you're using a BroadcastReceiver, then nothing will happen because an IntentService will fire the broadcast without any problems, but the Activity won't be able to receive the results since it's terminated.
But if you're simply creating a new Activity, then you can simply use startActivity() with the result data added to the Intent. Though, I doubt the user will be happy to see an Activity suddenly open on the screen when they're no longer in your app. Starting a new Activity has nothing to do with a previous Activity, since any instance of a Context can start an Activity.
Honestly, based on your question, it sounds like you're very concerned with an IntentService and it's connection with the Activity that started it. If that's the case, you really shouldn't be using an IntentService, since that's not really it's purpose. It's not meant to have a connection with an Activity. It's simply meant to do work and finish.
Instead, a bound Service would be a better option since it has a direct connection with the Activity that started it.

Is there a way for Activity to tell if the system is going to restart a Service after it has been killed by system?

Say I have an Activity that launches a Service using startService() when user presses a button. The service is stopped using another intent in startService() when user presses another button, or it can decide to stop itself. The service wants to run forever, so it returns START_STICKY from onStartCommand(). While the service is running, it connects to some server and receives messages. Activity binds to it and, when bound, displays those messages.
Now, when the Activity is started after an OOM kill, it doesn't know if the Service is started. One can use a static field set in onStartCommand() to tell if the Service is running, but that's prone to backfire sooner or later. Moreover, the Service can be started by the system after the activity has been launched, so using a static field is not an option at all.
The cleanest solution I can come up with is using SharedPreferences to store the state of the service. This is going to fail to be good when the service is killed between SharedPreferences.setBoolean("running", false) and stopSelf(), but such a thing will probably occur rarely.
Also I can try to bind to the Service at all times. This would be very ugly but still not impossible.
Any other solutions? Maybe the very idea is wrong in some way?

stop app, including all activities and services - android lifecycle

I would like to simply stop the app, and all its activities and services. Currently, from my main activity (which had started other activities), I call finish(), and the app appears to stop, as it goes to the home screen of my device. However, when I check running apps on the device, this app is still listed. It says "one process, and one service". Is there a way to just kill everything? Or, if I have to do it individually how would I find what is running, and how do I stop it? thanks
Is there some specific reason you want to make sure the process is killed?
Android manages processes intelligently. It keeps your process around, and if the user starts your app again it can use the existing process, rather than start up a new one. And if your device start running low on memory, Android will start killing off these inactive processes to free up resources.
In short, it's a good thing that Android keeps your process around. You shouldn't want to have it killed needlessly.
Although it sounds like you may not be stopping your application's service. If you use bindService to start the service from your activity, the service will automatically be stopped when the Activity is stopped (assuming nothing else has bound to the service). Alternately, if you use startService to start the service, you need to call stopService to stop it.

Long running Android 'service'

I have an Android app, in which Activities fire long running operations that run in the background. These operations interact with the Activities when done. I'm developing a component that handles the Activity/Long-Running-Task coupling, taking care of activities being destroyed and recreated.
Right now that component is implemented as an Android service. The activities call bindService and use the resulting IBinder to start and track tasks. I decided against using startService, because I prefer the richer API possible through a Java interface.
Now the problem. Activity A start ups, binds to the service and calls serviceApi.runTask(...). Activity A is then destroyed (because the user flips the phone, for instance) and recreated as Activity A'. A' then binds again to the service, announces its existence and everything should be running nicely.
Except that my Service gets destroyed. When Activity A is destroyed, it unbinds from the service. Android sees there are no more clients, and kills the service. When Activity A' is created, the service is created again, and I lose everything the old service had.
The only solution I can see is using a singleton for the service. And then it doesn't really have to be an Android service, just an instance that's accessible to everyone. Is that frowned upon in Android? Is there a better design that fits this problem?
Editted: Even if I call startService and then bind to it, nothing guarantees that the service instance will exist as long as the application is running. Android can kill sticky services if resources are low. Killing the service will cause the application to malfunction, and I can't have that.
Even if I call startService and then bind to it, nothing guarantees that the service instance will exist as long as the application is running.
Correct.
Android can kill sticky services if resources are low.
Also correct. All "sticky" means is that Android might restart the service.
Killing the service will cause the application to malfunction, and I can't have that.
It is impossible to create a service that is guaranteed to run forever. For starters, users can get rid of your service whenever they want, because users detest developers who have pointless services that run forever. Writing everlasting services is necessary only in very few cases; otherwise, it's just sloppy programming.
The only solution I can see is using a singleton for the service. And then it doesn't really have to be an Android service, just an instance that's accessible to everyone. Is that frowned upon in Android?
Singletons (a.k.a., static data members) will go away when the process is terminated. The process will be terminated eventually, particularly if there are no active services and none of your activities is in the foreground..
Call startService and in onStartCommand return START_STICKY. It should keep the service going.
You may also want to look into foreground services:
http://developer.android.com/reference/android/app/Service.html#startForeground(int, android.app.Notification)
Yo have to create persistent service. Refer to this manual.
In a few words - don't call bindService, call startService.

Android: Creating a service that survives the application that started it

I'm developing an Android application that consists of:
a lightweight background service that logs events to a DB
a heavier GUI application that summarizes these events and displays graphs.
I'm having trouble creating the service part, though. The graphic application can use quite some RAM, and when it goes to the background, the OS closes it after some time of not being used.
The problem is, when the application gets shut down, so does the service. This is bad because this keeps me from recording further events. I don't care if the application gets terminated, but the service needs to keep on running.
I have tried numerous ways to keep the service alive, like having it use threads or a differently named process than the main app. Nothing has worked, and I have found no help on any of the android developer pages or forums.
Thank you for your advice!
Try to return START_STICKY in your service's onStartCommand(). Also how do you start your service? If you use bindService() with BIND_AUTO_CREATE flag it will be stopped automatically on unbindService(). You should explicitly start it with startService() and stop calling stopSelf(). Than OS keep your process running on the background after activity will be closed. Note: the activity and the service run in one process and it's imposible: "application gets terminated, but the service needs to keep on running". But it is possible to keep the process running without activities, with service running on the background.
Read the detailed info http://developer.android.com/reference/android/app/Service.html.
good luck!
You should use the AlarmManager to respawn your service. You just can't keep your service alive eternally.
Check about the lifecycle : http://developer.android.com/guide/topics/fundamentals.html

Categories

Resources