我有一个绑定到应用程序上下文的服务,如下所示:
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
或检查它是否已绑定到服务?
提前致谢。
答案 0 :(得分:64)
试试这个:
boolean isBound = false;
...
isBound = getApplicationContext().bindService( new Intent(getApplicationContext(), ServiceUI.class), serviceConnection, Context.BIND_AUTO_CREATE );
...
if (isBound)
getApplicationContext().unbindService(serviceConnection);
注意:强>
您应该使用相同的context
来绑定服务并取消绑定服务。如果您使用getApplicationContext()
绑定服务,那么您还应该使用getApplicationContext.unbindService(..)
答案 1 :(得分:7)
Here您可以找到一个很好的解释和源代码如何使用绑定服务。在您的情况下,您应该覆盖onServiceConnected
对象的方法(onServiceDisconnected
和ServiceConnection
)。然后,您只需检查代码中的mBound
变量即可。
答案 2 :(得分:4)
确切地说安德烈诺维科夫提出的建议并不适用于我。 我只是替换了:
getApplicationContext().unbindService(serviceConnection);
使用:
unbindService(serviceConnection);
答案 3 :(得分:4)
我发现有两个问题。尝试绑定多次并尝试解除绑定多次。
解决方案:
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;
}
}
}
答案 4 :(得分:0)
我认为guide并不完全正确[{3}} 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
}
}
答案 5 :(得分:0)
为什么会出现此错误?
当您尝试注销未注册的服务时。
常见的例子有哪些?
unBind(mserviceConnection)
的电话多于bind(...)
第一点是不言而喻的。让我们更深入地探讨错误的第二个来源。调试您的bind()和unbind()调用。如果您看到按此顺序的呼叫,则您的应用程序最终将获得IllegalArgumentException
。
如何避免这种情况?
您应该考虑两种方法来绑定和取消绑定Activity中的服务。 Android文档建议
onStart()
中的bindService()和onStop()
中的unbindService()
Your Activity {
@Override
public void onStart(){
super.onStart();
bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
}
@Override
public void onStop(){
super.onStop();
unbindService(mConnection);
}
}
onCreate()
中的bindService()和onDestroy()
中的unbindService()
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);
}
}
答案 6 :(得分:0)
使用变量记录是否绑定到服务,如果变量为true,则取消绑定。
请参阅android官方示例:
答案 7 :(得分:-1)
对上述所有答案都不确定,它似乎太复杂了,而这些都不符合我的问题。
一次只绑定/解除绑定一次,并且在unbind()调用时服务肯定是绑定的。不想泄漏任何东西,所以我只是确保我对bind()和unbind()调用使用相同的上下文,并且永久地解决了它!做这样的事情:
any_context.getApplicationContext().bind(...);
...
another_context.getApplicationContext().unbind(...);