绑定服务vs在Android上启动服务以及如何做到这两点

时间:2013-04-23 05:58:03

标签: java android service binding

我问的是一个棘手的问题(部分地,在我看来),herehere。让我们说在许多例子中我们想要创建一个音乐应用程序,使用(比如说)单个活动和服务。我们希望在停止或销毁Activity时服务保持不变。这种生命周期建议启动服务:

  

当应用程序组件(例如   activity)通过调用startService()来启动它。一旦启动,服务   可以无限期地在后台运行,即使是那个组件   开始它被摧毁

好的,但我们也希望能够与服务进行通信,因此我们需要服务绑定。没问题,我们有this answer suggests的绑定和启动服务:

到目前为止一直很好,但问题是由于活动开始时我们不知道服务是否存在。它可能已经开始,或者可能没有。答案可能是这样的:

  • 在启动时,尝试绑定到服务(使用bindService()而不使用BIND_AUTO_CREATE标志)
  • 如果失败,则使用startService()启动服务,然后绑定到该服务。

这个想法的前提是特定阅读bindService()的文档:

  

连接到应用程序服务,根据需要创建它。

如果零标志意味着“真的不需要服务”,那么我们就可以了。所以我们使用以下代码尝试这样的事情:

private void connectToService() {
    Log.d("MainActivity", "Connecting to service");
    // We try to bind to an existing service
    Intent bindIntent = new Intent(this, AccelerometerLoggerService.class);
    boolean bindResult = bindService(bindIntent, mConnection, 0);
    if (bindResult) {
        // Service existed, so we just bound to it
        Log.d("MainActivity", "Found a pre-existing service and bound to it");
    } else {
        Log.d("MainActivity", "No pre-existing service starting one");
        // Service did not exist so we must start it

        Intent startIntent = new Intent(this, AccelerometerLoggerService.class);
        ComponentName startResult = startService(startIntent);
        if (startResult==null) {
            Log.e("MainActivity", "Unable to start our service");
        } else {
            Log.d("MainActivity", "Started a service will bind");
            // Now that the service is started, we can bind to it
            bindService(bindIntent, mConnection, 0);
            if (!bindResult) {
                Log.e("MainActivity", "started a service and then failed to bind to it");
            } else {
                Log.d("MainActivity", "Successfully bound");
            }
        }
    }
}

我们得到的是每次成功的绑定:

04-23 05:42:59.125: D/MainActivity(842): Connecting to service
04-23 05:42:59.125: D/MainActivity(842): Found a pre-existing service and bound to it
04-23 05:42:59.134: D/MainActivity(842): onCreate

全球性的问题是“我是否误解了绑定与已启动的服务以及如何使用它们?”更具体的问题是:

  • 认为传递给bindService()的零标志意味着“不启动服务”是对文档的正确理解吗?如果没有,如果没有启动服务,是否无法呼叫bindService()
  • 为什么即使服务未运行,bindService()也会返回true?在这种情况下,基于Log调用,服务似乎没有启动。
  • 如果上一点是bindService()的正确/预期行为,是否有解决方法(即以某种方式确保仅在服务未运行时才调用startService?)

P.S。我已经从我自己的代码中解决了问题:我发出了startService()次调用,因为重复的startService()被忽略了。但是,我仍然希望更好地理解这些问题。

1 个答案:

答案 0 :(得分:2)

  1. 如果使用0标志bindService,则服务将无法启动。您可以使用BIND_AUTO_CREATE标志bindService,如果服务未启动,它将被启动。但是,当您取消绑定服务时,服务将被销毁。
  2. 带有0标志的bindService始终返回true。
  3. 您始终可以调用startService。如果该服务已在运行,则不会创建新服务。将调用正在运行的服务onStartCommand。
  4. 如果在onCreate中启动service,然后在onResume中使用bindService,在onPause中使用unbindService,那么应该没有任何问题。