从 activity 正确解除绑定服务

Properly unbind service from activity

我有一个简单的 android 应用程序,其中包含一个绑定服务的 activity。基本代码是这样的:

public class MyActivity extends AppCompatActivity {
    private MyService service;
    private boolean serviceIsBound;

    private final ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            service = ((MyService.LocalBinder) binder).getService();
            serviceIsBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            serviceIsBound = false;
        }
    };
    
    // Service gets bound via intent in onCreate()

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (serviceIsBound) {
            service.unbindService(serviceConnection);
        }
    }
}

当我关闭 activity.

时,这会在 service.unbindService(...) 调用中产生错误 java.lang.IllegalArgumentException: Service not registered

我试过 onStop() 而不是 onDestroy() --> 同样的错误。 我尝试删除 onDestroy() --> 我收到错误 android.app.ServiceConnectionLeaked。这个错误当然是有道理的——毕竟你应该清理你的服务连接。我就是不知道怎么办。

在调用 bindService() 的同一 Context 上调用 unbindService()。据推测,鉴于您的样本结构,您正在 MyActivity 实例上调用 bindService() ;如果是这样,在 MyActivity 实例上也调用 unbindService()


请注意,您可能不应该这样做。在配置更改(例如,屏幕旋转)时,您的 MyActivity 实例将被销毁并重新创建。这意味着您将解除与该服务的绑定,然后再次绑定到它。如果没有其他东西绑定到该服务,并且该服务没有启动,该服务将被销毁(当它未绑定时)然后重新创建(当新的 activity 实例再次绑定时)。

您很可能不需要绑定服务,尤其是当该服务与您的应用程序的其余部分处于同一进程时。如果您确定需要绑定服务,请绑定和取消绑定在配置更改后仍然存在的内容,例如 AndroidViewModel。在那里,您将使用 Application 作为 bind/unbind 调用的 Context。或者,如果您使用的是依赖倒置 (DI) 框架(例如 Dagger/Hilt、Koin),您可能会从中得到 Context。或者,如果合适的话,从一些 DI 管理的单例中绑定和解除绑定,再次使用 Application 作为你的 `Context.

FWIW,this sample app contains a bound service. It is used by this client app,从 ViewModel.

绑定和解除绑定