Tomasz Gawel
Tomasz Gawel

Reputation: 8520

Android bound service - should I manually reconnect in onServiceDisconnected or it tries reconnect automatically?

If i get disconnected from bound service due to some unexpected circumstances, after i called, should I manually reconnect in onServiceDisconnected or it tries to reconnect automatically?

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

Upvotes: 10

Views: 6771

Answers (2)

Vasiliy
Vasiliy

Reputation: 16258

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.

Upvotes: 12

yorkw
yorkw

Reputation: 41126

According to the ServiceConnection API:

public abstract void onServiceDisconnected (ComponentName name)

Called when a connection to the Service has been lost. This typically happens when the process hosting the service has crashed or been killed. This does not remove the ServiceConnection itself -- this binding to the service will remain active, and you will receive a call to onServiceConnected(ComponentName, IBinder) when the Service is next running.

Back to your question:

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

It is all depend on which process the actual service lives.

Local Service:

Service is running in the same process as other components (i.e. activity that bound to it) from the same application, when this single application-scoped process has crashed or been killed, it is very likely that all components in this process (include the activity that bound to this service) are also destroyed. In this case, calling connect() inside onServiceDisconnected() doesn't make any effect, as when application process is recovered, everything is rolling over from very beginning and the activity is recreated again and service is bound in activity's onStart() callback.

Remote Service:

Service is running in separate process, when this process has crashed or been killed, only the actual service is destroyed, the activity lives in another process that bound to the service is remained, so it is probably OK to call connect() in its onServiceDisconnected() callback in order to re-create/re-bind the service.

Check out here to see how to configure service running on separate process in AndroidManifest.xml.

Upvotes: 15

Related Questions