Android绑定服务 - 我应该手动重新连接onServiceDisconnected还是尝试自动重新连接?

Tom*_*wel 9 android android-service

如果由于某些意外情况我从绑定服务断开连接,在我打电话后,我应该手动重新连接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();
    }
}
Run Code Online (Sandbox Code Playgroud)

yor*_*rkw 12

根据ServiceConnection API:

public abstract void onServiceDisconnected(ComponentName name)

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

回到你的问题:

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

这完全取决于实际服务所处的过程.

本地服务:

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

远程服务:

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

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


Vas*_*liy 7

在为博客文章进行研究时,将这个老问题归结为这个问题.接受的答案非常好,但在绑定IPC(远程)服务时并未显示整个画面.

绑定IPC服务连接的状态图如下所示:

在此输入图像描述

OP的问题的答案是:它取决于.

首先 - 当服务崩溃或被操作系统杀死时,它仍然受到约束.所以问题在于系统是否会重新创建服务......

  • 如果绑定的IPC服务被操作系统杀死,它将被重新创建并且您将接到一个电话onServiceConnected(),因此无需"重新连接".
  • 如果绑定的IPC服务崩溃,系统将尝试重新创建一次 - 如果它第二次崩溃,系统将不会再次重新创建它(在JellyBean,Lollipop和Marshmallow上测试).

理论上,你可以unbindService(),然后bindService()每次打电话onServiceDisconnected()- 这应该工作(我认为).

但是,为绑定的IPC服务编写一个非常可靠的客户端需要更多的工作,并且可以在这里找到一般的想法(以及教程应用程序).