I am trying to create a sticky service that is bindable to (I need to run potentially asynchronic operations in the background on some data that the service holds). To do this, I need to be sure that onBind always runs after onStartCommand. Is there any way to guarantee this?
From your requirements, you probably don't need to bind to your Service
. Then using an IntentService
would suffice, as this service will stop itself after its work is done.
Taken from the docs:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
An example of an IntentService
:
public class MyService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
// Do some work here, get Intent extras if any, etc.
// ...
// Once this method ends, the IntentService will stop itself.
}
}
}
More info on how to create an IntentService
can be found here.
That can handle your asynchronous operations. And if you need any feedback, which will "break" the async part of the requirement, you could use a LocalBroadcastManager
or as you said, you could bind to this Service
. And then again, it depends on what you're trying to do.
From the docs, you have two types of services.
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.
Reminder: You can start a Service
through startService()
to make it run "indefinitely" and bind to it by calling onBind()
later.
Intent it = new Intent(this, MyService.class);
startService(it); // Start the service.
bindService(it, this, 0); // Bind to it.
If you want to simply run this service for as long as your Activity
is running, you could just call onBind()
.
Intent it = new Intent(this, MyService.class);
bindService(it, this, 0); // This will create the service and bind to it.
More info on "default" Service
, how to use it and implement it can be found here.
Just choose what works best for your use case, and you're good to go.
The point is, you're not supposed to call both startService() and bindService(). If you want to bind to a service, call bindService(). When the service is connected, your implementation of ServiceConnection.onServiceConnected() is called, giving you an IBinder to the Service. Typically, a bound service is used as the server part of an internal client-server interface. You bind to the service, get back an IBinder that gives you a handle to the Service object itself, and then use the Service handle to pass data or call methods in the Service.
Bound services are almost always used to connect between processes (IPC).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With