Android:如何安全地解除绑定服务
我有一个服务绑定到这样的应用程序上下文:
getApplicationContext().bindService( new Intent(this, ServiceUI.class), serviceConnection, Context.BIND_AUTO_CREATE ); protected void onDestroy() { super.onDestroy(); getApplicationContext().unbindService(serviceConnection); }
出于某种原因,只有有时应用程序上下文不能正确绑定(我不能修复该部分),但是在onDestroy()我做unbindservice
这会引发错误
java.lang.IllegalArgumentException: Service not registered: tools.cdevice.Devices$mainServiceConnection.
我的问题是:是否有一种方法来安全地调用unbindservice
或检查它是否已经绑定到服务之前解除绑定?
提前致谢。
尝试这个:
boolean isBound = false; ... isBound = getApplicationContext().bindService( new Intent(getApplicationContext(), ServiceUI.class), serviceConnection, Context.BIND_AUTO_CREATE ); ... if (isBound) getApplicationContext().unbindService(serviceConnection);
注意:
您应该使用相同的context
来绑定服务和解除绑定服务。 如果你使用getApplicationContext()
绑定Service,那么你也应该使用getApplicationContext.unbindService(..)
在这里你可以find一个很好的解释和源代码如何使用绑定的服务。 在你的情况下,你应该覆盖ServiceConnection
对象的方法( onServiceConnected
和onServiceDisconnected
)。 然后你可以在代码中检查mBound
variables。
做什么Andrey Novikovbuild议没有为我工作。 我简单地replace了:
getApplicationContext().unbindService(serviceConnection);
附:
unbindService(serviceConnection);
我发现有两个问题。 尝试绑定不止一次,并尝试不止一次地解除绑定。
解:
public class ServiceConnectionManager implements ServiceConnection { private final Context context; private final Class<? extends Service> service; private boolean attemptingToBind = false; private boolean bound = false; public ServiceConnectionManager(Context context, Class<? extends Service> service) { this.context = context; this.service = service; } public void bindToService() { if (!attemptingToBind) { attemptingToBind = true; context.bindService(new Intent(context, service), this, Context.BIND_AUTO_CREATE); } } @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { attemptingToBind = false; bound = true; } @Override public void onServiceDisconnected(ComponentName componentName) { bound = false; } public void unbindFromService() { attemptingToBind = false; if (bound) { context.unbindService(this); bound = false; } } }
不能确定所有上述的答案,似乎太复杂,而这些都不符合我的问题。
一次只绑定/解除绑定,并且在unbind()调用时绑定服务。 不要泄漏任何东西,所以我只是确保我正在使用相同的上下文的bind()和unbind()调用,并永久解决它! 做这样的事情:
any_context.getApplicationContext().bind(...); ... another_context.getApplicationContext().unbind(...);
我认为这个指南并不完全正确,就像这里提到的Surya Wijaya Madjid一样。 内存泄漏可能发生在绑定服务被取消且尚未重新连接。
我认为这种方法是必要的:
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 } }