Android:如何安全地取消绑定服务

2nd*_*ife 41 android

我有一个绑定到应用程序上下文的服务,如下所示:

getApplicationContext().bindService(
                    new Intent(this, ServiceUI.class),
                    serviceConnection,
                    Context.BIND_AUTO_CREATE
            );

protected void onDestroy() {
            super.onDestroy();                  
            getApplicationContext().unbindService(serviceConnection);
        }
Run Code Online (Sandbox Code Playgroud)

出于某种原因,有时只有应用程序上下文没有正确绑定(我无法修复该部分),但是在onDestroy()中我做了unbindservice哪个会抛出错误

java.lang.IllegalArgumentException: Service not registered: tools.cdevice.Devices$mainServiceConnection.
Run Code Online (Sandbox Code Playgroud)

我的问题是:unbindservice在解除绑定之前,有没有办法安全地打电话或检查它是否已绑定到服务?

提前致谢.

And*_*kov 65

试试这个:

boolean isBound = false;
...
isBound = getApplicationContext().bindService( new Intent(getApplicationContext(), ServiceUI.class), serviceConnection, Context.BIND_AUTO_CREATE );
...
if (isBound)
    getApplicationContext().unbindService(serviceConnection);
Run Code Online (Sandbox Code Playgroud)

注意:

您应该使用它context来绑定服务和解除绑定服务.如果您绑定服务,getApplicationContext()那么您也应该使用getApplicationContext.unbindService(..)

  • 我的问题似乎源于使用活动上下文而不是应用程序上下文.为了防止篡改您正在使用的上下文,如上所述,请确保您使用应用程序上下文进行所有绑定/解除绑定. (3认同)

Yur*_*ury 7

在这里,您可以找到一个很好的解释和源代码如何使用绑定服务.在您的情况下,您应该覆盖对象的方法(onServiceConnectedonServiceDisconnected)ServiceConnection.然后你可以检查mBound代码中的变量.

  • 与本地服务不同,如果目标服务的进程终止,并且在重新启动时将再次传递`onServiceConnected()`,则绑定到远程服务将为我们提供`onServiceDisconnected()`回调.如果您依赖于`mBound`标志的那些回调,如果在`onServiceDisconnected()`和`onServiceConnected()`之间进行取消绑定的尝试,当`mBound`将是'false`时,您将获得服务连接泄漏. (4认同)
  • 404.回答发布链接而不是摘录应该是鼓励 (2认同)

小智 5

完全按照安德烈·诺维科夫的建议做对我没有用。我简单地替换为:

getApplicationContext().unbindService(serviceConnection);
Run Code Online (Sandbox Code Playgroud)

带有:

unbindService(serviceConnection);
Run Code Online (Sandbox Code Playgroud)

  • 什么是** serviceConnection **? (2认同)

Blu*_*ell 5

我发现有两个问题。尝试绑定不止一次,并且尝试解除绑定不止一次。

解:

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;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 这可行,但是您必须手动维护“ bound”确实很尴尬-似乎它应该是一个可访问的内部变量。 (2认同)