9

如果由于某些意外情况而与绑定服务断开连接,在我调用之后,我应该在 onServiceDisconnected 中手动重新连接还是尝试自动重新连接?

public class MyServiceConnection extends Activity implements ServiceConnection {

    MyBinder binder;

    @Override
    protected void onStart() {
        super.onStart();

        connect();
    }

    private void connect() {
        bindService(new Intent(this, MyService.class), 
                this, Service.BIND_AUTO_CREATE);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        binder = (MyBinder) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

        binder = null;

        //should i reconnect here ?
        connect();
    }
}
4

2 回答 2

15

根据ServiceConnection API

公共抽象无效 onServiceDisconnected(组件名称名称)

当与服务的连接丢失时调用。这通常发生在托管服务的进程崩溃或被终止时。这不会删除 ServiceConnection 本身 - 与服务的绑定将保持活动状态,并且当服务下次运行时,您将收到对 onServiceConnected(ComponentName, IBinder) 的调用。

回到你的问题:

@Override
public void onServiceDisconnected(ComponentName name) {
    binder = null;
    //should i reconnect here ?
    connect();
}

这完全取决于实际服务的进程。

本地服务:

服务与来自同一个应用程序的其他组件(即绑定到它的活动)在同一进程中运行,当这个单个应用程序范围的进程崩溃或被杀死时,很可能该进程中的所有组件(包括活动绑定到该服务的)也被销毁。在这种情况下,在 onServiceDisconnected() 中调用 connect() 不会产生任何效果,因为当应用程序进程恢复时,一切都从头开始滚动,并且再次重新创建活动,并且服务绑定在活动的 onStart() 回调中。

远程服务:

服务在单独的进程中运行,当该进程崩溃或被杀死时,只有实际的服务被销毁,活动在另一个绑定到该服务的进程中仍然存在,因此在其 onServiceDisconnected 中调用 connect() 可能是可以的() 回调以重新创建/重新绑定服务。

此处查看如何在 AndroidManifest.xml 中配置在单独进程上运行的服务。

于 2012-05-24T23:31:35.327 回答
10

Bumped into this old question when making a research for a blog post. The accepted answer is quite good, but does not show the entire picture when it comes to bound IPC (remote) services.

State diagram of a connection to bound IPC service looks like this:

enter image description here

And the answer to OP's question is: it depends.

First of all - when service crashes or being killed by OS it remains bound. So the question becomes whether the system will re-create the service or not...

  • In case bound IPC service is being killed by OS, it will be re-created and you'll get a call to onServiceConnected(), therefore no need to "reconnect".
  • In case bound IPC service crashes, the system will attempt to re-create it once - if it crashes for the second time the system will not re-create it again (tested on JellyBean, Lollipop and Marshmallow).

Theoretically, you could unbindService() and then bindService() on each call to onServiceDisconnected() - this should work (I think).

However, writing a really reliable client for bound IPC service is a bit more work, and the general idea (alongside tutorial app) could be found here.

于 2016-06-09T23:30:29.033 回答