In one case, one service being started by another component runs on the main UI thread of that component, while the service may live even that component is destroyed, so my question is where to execute the service if the component started that service is stopped?
Typically, when you call startService(), the service will remain running until you call stopService() from another component or stopSelf() from the service itself. And onStartCommand() will always run on UI thread.
If the service is running, subsequent calls to startService() will not create another instance of your service but run onStartCommand() again on the running one. This is slightly different if you are binding your component to a service. In this case, the service is automatically destroyed when you unbind all components. For more details on this, see: http://developer.android.com/guide/components/services.html#Lifecycle.
In addition, note that there different ways to keep a service running, depending on what you return from the onStartCommand():
START_STICKY is used for services that are explicitly started and
stopped as needed, while START_NOT_STICKY or START_REDELIVER_INTENT
are used for services that should only remain running while processing
any commands sent to them.
To answer your question specifically, where and how to start your service depends on what exactly you want to do with it. If the component that started the service stopped, it is up to you to either 1) get a new reference to the service from another component and stop it or 2) stop the service from the service itself. But the service won't stop because the component did. Unless you are binding it to the service.
Related
In the bound services documentation, it says
When a service is unbound from all clients, the Android system destroys it (unless it was also started with a startService() call). As such, you don't have to manage the lifecycle of your service if it's purely a bound service—the Android system manages it for you based on whether it is bound to any clients.
However, if you choose to implement the onStartCommand() callback method, then you must explicitly stop the service, because the service is now considered to be started. In this case, the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.
Does this mean that simply implementing onStartCommand automagically puts the service into a started state when a client binds to it?
I've been looking for a way to guarentee that when a client binds to the service, the service is in the started state. So far, the only way I've been able to do it is by having the client call startService followed by bindService. But if the above is correct, then all I have to do is implement onStartCommand and the client is free to just call bindService.
I agree that the documentation is wrong. Simply implementing onStartCommand() changes nothing. Especially because you don't implement it, you override the method, because there is already an existing default implementation of onStartCommand()
When you bind to a Service, the Service isn't technically "started", it is just bound. onStartCommand() will not be called unless something calls startService().
I am trying to run a service in the background, despite the lifecycle state of the Activity that creates it. To guarantee it's running, the service (in addition to the services it performs) also has a thread that logs once a second. Finally, it also has logs in onStartCommand and onDestroy.
I'm starting the service with startService() and then I bind to it. My understanding is that this should keep the service running, regardless of what happens to its creator Activity. However, if the Activity is destroyed, the service stops logging. If the Activity is simply paused, there is no problem.
The following is also true:
1) onDestroy is never called on the service
2) I never call stopService or stopSelf after calling startService
I'm trying to figure out why the service is dying (there are no exceptions) or at the very least why it's being paused and no longer logging.
A bound service typically lives only while it serves application component and does not run in the background indefinitely.
http://developer.android.com/guide/components/services.html
http://developer.android.com/guide/components/bound-services.html
Use syncadapter instead of service . if you want to transfer data between server and client .
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html
I would like to know when it is smart to use bindService and when to use startService.
For example:
If I use bindService with BIND_AUTO_CREATE, the service will be started and created automatically as is written here: http://developer.android.com/reference/android/content/Context.html#BIND_AUTO_CREATE
When is it smart then to use bindService and when startService? I really don't understand these two correctly.
You usually use bindService() if your calling component(Activity) will need to communicate with the Service that you are starting, through the ServiceConnection. If you do not want to communicate with the Service you can use just startService(). You Can see below diffrence between service and bind service.
From the docs :
Started
A service is "started" when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.
Bound
A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.
You can read more here : Android Services, Bound Services
I agree with #Ovidiu Latcu but with one important note:
when using bound services, the service is ended when the activity that started it is ended, (if it is the only activity bound to that service).
So if you want to run your service at the background while the app is in the background,
(the activity is paused for example and not visible to the user) then you must start the service without bounding to it and communicate with it with BroadcastReceiver for example.
I'm developing a Android Service. I would like the service to run even when the application not is active. So I start it without binding it:
startService(new Intent(Service.class.getName()));
Now it will run continuously until I choose to stop it, right?
If I, from another activity, bind the service will it stop when I unbind it?
Not necessarily. However, you have to remember that if there is memory pressure, it may be killed depending on the priorities (and if it is unbound, any visible app will probably have higher priority). The lifecycle is described here:
http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle
When the last client unbinds from the service, the system destroys the service (unless the service was also started by startService()).
It mean that your service will not stop even you unbind service from all activity in case of you had started service as startService()
For more details about bound service follow bellow link
Bound services
I'm a little confused on how binding to services works. I understand using Context.startService() starts the service and that bindService doesn't call onStartCommand. But my understanding is that if I use startService, I have to explicitly stop the service. But I want the service to die if there are no more activities bound to it.
My problem is that calling bindService never calls onServiceConnected(), so my Service binder object is null. Does the service have to be explicitly started in order to bind to it? If so, how does it know to terminate when nothing is binding to it anymore, and how do I know if it's started so I can know to use the bound object?
if you call bindService with BIND_AUTO_CREATE as flag the system will bind your activity to the service if it exists, otherwise if it doesn't exist the system will start the service for you and then it will bind your activity to the service. Furthermore if you start a Service in this way the service will remain active only if it has still some context binded.
this is from bindService():
Connect to an application service, creating it if needed. This defines a dependency between your application and the service. The given conn will receive the service object when its created and be told if it dies and restarts. The service will be considered required by the system only for as long as the calling context exists. For example, if this Context is an Activity that is stopped, the service will not be required to continue running until the Activity is resumed
and this is from ServiceLyfecycle
A service can be both started and have connections bound to it. In such a case, the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy() method is called and the service is effectively terminated. All cleanup (stopping threads, unregistering receivers) should be complete upon returning from onDestroy().
The answer is that I wasn't waiting for the service to actually be bound before using it, since it gets bound asynchronously
You should be setting up your binder in onBind and any generic setup in onCreate. The behaviour of starting and binding services is explained at http://developer.android.com/reference/android/app/Service.html#ServiceLifecycle