I'm trying to create a service that is primarily run in the foreground and clients can bind to it only if it is already in the started state. However, every potential solution I can come up with is riddled with race conditions.
The most promiment example of this:
final ServiceConnection serviceConnection = // create instance...
void startAndBindToService() {
final Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
// this *sometimes* doesn't bind because the service isn't started yet
bindService(serviceIntent, serviceConnection, 0);
}
Testing on an emulator, the above works consistently on a local service but not when the service is in another process.
I've also looked into having the service starting itself when its onBind
method is called:
@Override
public void IBinder onBind(Intent intent) {
startService(new Intent(this, this.getClass()));
return binder;
}
But this never guarantees the service will be in the started state before the client unbinds.
And for the ones that think they are clever and ask why I don't use BIND_AUTO_CREATE
, that doesn't solve the problem, and in fact it only makes it worse. BIND_AUTO_CREATE
only creates the service, it doesn't put it in the started state, but it does allow for the service to end being created twice if a race condition does occur.