I have a service which is binded to application context like this:
getApplicationContext().bindService(
new Intent(this, ServiceUI.class
Here you can find a nice explanation and source codes how to work with bound services. In your case you should override methods (onServiceConnected
and onServiceDisconnected
) of ServiceConnection
object. Then you can just check mBound
variable in your code.
I think that guide is not completely correct as mentioned here Surya Wijaya Madjid. Memory leaks can occur when bound service is destryed and not re-connected yet.
I think that this approach is needed:
Service mService;
private final ServiceConnection mServiceConnection = new ServiceConnection()
{
boolean bound = false;
@Override
public void onServiceDisconnected(ComponentName name)
{
mService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
mService = ((MyService.ServiceBinder) service).getService();
if (!bound)
{
// do some action - service is bound for the first time
bound = true;
}
}
};
@Override
public void onDestroy()
{
if (mService != null)
{
// do some finalization with mService
}
if (mServiceConnection.bound)
{
mServiceConnection.bound = false;
unbindService(mServiceConnection);
}
super.onDestroy();
}
public void someMethod()
{
if (mService != null)
{
// to test whether Service is available, I have to test mService, not mServiceConnection.bound
}
}
Use a variable to record if you have ever bind to a service, and unbind it if the variable is true.
See android official example :
http://androidxref.com/9.0.0_r3/xref/development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java#376
Try this:
boolean isBound = false;
...
isBound = getApplicationContext().bindService( new Intent(getApplicationContext(), ServiceUI.class), serviceConnection, Context.BIND_AUTO_CREATE );
...
if (isBound)
getApplicationContext().unbindService(serviceConnection);
Note:
You should use same context
for binding a service and unbinding a service. If you are binding Service with getApplicationContext()
so you should also use getApplicationContext.unbindService(..)
Doing exactly what Andrey Novikov proposed didn't work for me. I simply replaced:
getApplicationContext().unbindService(serviceConnection);
With:
unbindService(serviceConnection);
Why do we get this error?
When you try to unregister a service which is not registered.
What are some common examples?
unBind(mserviceConnection)
more than bind(...)
First point is self explanatory. Lets explore the second source of error more deeply. Debug your bind() and unbind() calls. If you see calls in these order then your application will end up getting the IllegalArgumentException
.
How can we avoid this?
There are two ways you should consider to bind and unbind a service in Activity. Android docs recommend that
bindService() in
onStart()
and unbindService() inonStop()
Your Activity {
@Override
public void onStart(){
super.onStart();
bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
}
@Override
public void onStop(){
super.onStop();
unbindService(mConnection);
}
}
bindService() in
onCreate()
and unbindService() inonDestroy()
Your Activity {
@Override
public void onCreate(Bindle sis){
super.onCreate(sis);
....
bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}