何时启动并绑定服务已销毁?

anz*_*anz 54 android android-service

当我注意到两个相互矛盾的观点时,我正在浏览android中的服务文档:

在服务文档中,它在" 管理服务的生命周期"中指定

这两条路径并不完全分开.也就是说,您可以绑定到已使用startService()启动的服务.例如,可以通过使用标识要播放的音乐的Intent调用startService()来启动背景音乐服务.之后,可能当用户想要对播放器进行一些控制或获取有关当前歌曲的信息时,活动可以通过调用bindService()绑定到服务.在这种情况下,stopService()或stopSelf()实际上不会停止服务,直到所有客户端解除绑定.

但是在关于管理绑定服务的生命周期中的绑定服务的文档中

但是,如果您选择实现onStartCommand()回调方法,则必须显式停止该服务,因为现在认为该服务已启动.在这种情况下,服务一直运行,直到服务使用stopSelf()或其他组件调用stopService()停止自身,无论它是否绑定到任何客户端.

可能是我,但我认为这些陈述是矛盾的.有人可以澄清......

Chu*_*ger 81

同意文档可以更清楚.他们想说的是:

  • 如果你调用startService(),那么服务将继续运行,除非你直接从服务中调用stopSerivce()(或stopSelf())
  • 如果你调用bindService(),那么服务将继续运行,除非你调用unbindService()
  • 因此,如果同时调用startService()和bindService(),则服务将继续运行,直到您同时调用stopService和unbindService().它本身都不会停止服务.

创建了一个非常简单的Activity和Service,并运行了以下start/stop/bind/unbind序列.我观察到这些调用给出了以下结果.

绑定,解除绑定

bindService() caused:
    onCreate()
    onBind()
unbindService() caused:
    onUnbind()
    onDestroy()
Run Code Online (Sandbox Code Playgroud)

启动绑定,解除绑定停

startService() caused:
    onCreate()
    onStartCommand()
bindService() caused:
    onBind()
unbindService() caused:
    onUnbind()
stopService() caused:
    onDestroy()
Run Code Online (Sandbox Code Playgroud)

启动绑定一站式解除绑定

startService() caused:
    onCreate()
    onStartCommand()
bindService() caused:
    onBind()
stopService() caused:
    -- nothing
unbindService() caused:
    onUnbind()
    onDestroy()
Run Code Online (Sandbox Code Playgroud)

结合起停,解除绑定

bindService() caused:
    onCreate()
    onBind()
startService() caused:
    onStartCommand()
stopService() caused:
    -- nothing -- still running
unbindService() caused:
    onUnbind()
    onDestroy()
Run Code Online (Sandbox Code Playgroud)

BIND的启动解除绑定停

bindService() caused:
    onCreate()
    onBind()
startService() caused:
    onStartCommand()
unbindService() caused:
    onUnbind()
stopService() caused:
    onDestroy()
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在调用bind和start的每种情况下,服务都会一直运行,直到调用unbind和stop.解绑/停止的顺序并不重要.

以下是我的简单测试应用程序中单独按钮调用的示例代码:

public void onBindBtnClick(View view) {
    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

public void onUnbindBtnClick(View view) {
    if (serviceIsBound) {
        unbindService(serviceConnection);
        serviceIsBound = false;
    }
}

public void onStartBtnClick(View view) {
    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    startService(intent);
}

public void onStopBtnClick(View view) {
    Intent intent = new Intent(MainActivity.this, ExampleService.class);
    exampleService.stopService(intent);
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的研究 (9认同)

Ste*_*han 55

实际上,两个段落相互补充(虽然它们的措辞可能是错误的),并且两个段落都与文档中的图像一致.我们来看一下:

这两条路径并不完全分开.也就是说,您可以绑定到已使用startService()启动的服务.例如,可以通过使用标识要播放的音乐的Intent调用startService()来启动背景音乐服务.之后,可能当用户想要对播放器进行一些控制或获取有关当前歌曲的信息时,活动可以通过调用bindService()绑定到服务.在这种情况下,stopService()或stopSelf()实际上不会停止服务,直到所有客户端解除绑定.

精髓是:如果启动服务,然后将客户端绑定到它,然后尝试停止它,则在所有客户端解除绑定之前不停止(销毁)服务.第二段并不矛盾,它改进了这一陈述.

但是,如果您选择实现onStartCommand()回调方法,则必须显式停止该服务,因为现在认为该服务已启动.在这种情况下,服务一直运行,直到服务使用stopSelf()或其他组件调用stopService()停止自身,无论它是否绑定到任何客户端.

这意味着:即使没有客户端绑定到它,直到明确停止,启动和绑定的服务仍会运行.当然,措辞可能会更清楚一些.然而,文档中给出的生命周期图显示了这一点(我很确定我已经在"现实生活中"观察到了这一点,尽管我目前还没有直接的例子):

启动和绑定服务的生命周期

  • 根据混合服务中的这个图,在调用所有客户端Unbind onDestroy()之后.这是正确的吗?onUnbind()和onDestroy()之间是否应该存在直接链接? (2认同)