I am asking a vexed question that has been (partially, to my mind) addressed here and here. Let's say like in many examples we want to create a music application, using (say) a single activity and a service. We want the service to persist when the Activity is stopped or destroyed. This kind of lifecycle suggests a started service:
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
Ok, but we also want to be able to communicate with the service, so we need a service binding. No problem, we have both a bound and started service as this answer suggests:
So far so good, but a problem arises from the fact that when the activity starts, we do not know if the service is around or not. It may have been started or it may not have been. The answer could be something like:
startService()
, and then bind to it.This idea is premised on a particular reading of the docs for bindService()
:
Connect to an application service, creating it if needed.
If zero flag means "service is not really needed" than we are OK. So we try something like this using the following code:
private void connectToService() {
Log.d("MainActivity", "Connecting to service");
// We try to bind to an existing service
Intent bindIntent = new Intent(this, AccelerometerLoggerService.class);
boolean bindResult = bindService(bindIntent, mConnection, 0);
if (bindResult) {
// Service existed, so we just bound to it
Log.d("MainActivity", "Found a pre-existing service and bound to it");
} else {
Log.d("MainActivity", "No pre-existing service starting one");
// Service did not exist so we must start it
Intent startIntent = new Intent(this, AccelerometerLoggerService.class);
ComponentName startResult = startService(startIntent);
if (startResult==null) {
Log.e("MainActivity", "Unable to start our service");
} else {
Log.d("MainActivity", "Started a service will bind");
// Now that the service is started, we can bind to it
bindService(bindIntent, mConnection, 0);
if (!bindResult) {
Log.e("MainActivity", "started a service and then failed to bind to it");
} else {
Log.d("MainActivity", "Successfully bound");
}
}
}
}
And what we get is a successful binding every time:
04-23 05:42:59.125: D/MainActivity(842): Connecting to service
04-23 05:42:59.125: D/MainActivity(842): Found a pre-existing service and bound to it
04-23 05:42:59.134: D/MainActivity(842): onCreate
The global question is "Am I misunderstanding bound versus started services and how to use them?" More specific questions are:
bindService()
means "Do not start the service"? If not, is there no way to call bindService()
without starting the service?bindService()
return true
even if the service is not running? In this case it doesn't seem like the service has been started, based on Log
calls.bindService()
, is there a workaround (i.e. somehow ensure that startService
is called only if the service is not running?)P.S. I've moved on from the problem in my own code: I issue startService()
calls regardless, since repeated startService()
are simply ignored. However, I would still like to understand the issues better.
There should not be any problem if you startService in onCreate and then bindService in onResume and unbindService in onPause.
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