Java Android上绑定服务与启动服务的比较以及如何做到两者

Java Android上绑定服务与启动服务的比较以及如何做到两者,java,android,service,binding,Java,Android,Service,Binding,我在问一个已经(部分地,在我看来)解决和解决了的棘手问题。让我们假设像在许多例子中一样,我们希望创建一个音乐应用程序,使用(比如)单个活动和服务。我们希望该服务在活动停止或销毁时保持不变。这种生命周期表示已启动的服务: 当应用程序组件(例如 活动)通过调用startService()启动它。一旦启动,服务 可以无限期地在后台运行,即使组件 它被摧毁了 好的,但是我们也希望能够与服务通信,所以我们需要一个服务绑定。没问题,我们的绑定和启动服务都是: 在活动启动时(或其他点),我们调用 之后,我们

我在问一个已经(部分地,在我看来)解决和解决了的棘手问题。让我们假设像在许多例子中一样,我们希望创建一个音乐应用程序,使用(比如)单个活动和服务。我们希望该服务在活动停止或销毁时保持不变。这种生命周期表示已启动的服务:

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

好的,但是我们也希望能够与服务通信,所以我们需要一个服务绑定。没问题,我们的绑定和启动服务都是:

  • 在活动启动时(或其他点),我们调用
  • 之后,我们调用以获取接口,并从那里继续
到目前为止还不错,但问题在于,当活动开始时,我们不知道服务是否存在。它可能已经启动,也可能尚未启动。答案可能是这样的:

  • 在启动时,尝试绑定到服务(使用时不带标志)
  • 如果失败,则使用
    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
另外,我已经从我自己的代码中的问题转移到了另一个问题上:不管怎样,我都会发出
startService()
调用,因为重复的
startService()
会被忽略。不过,我还是想更好地理解这些问题

  • 如果使用0标志绑定服务,则该服务将不会启动。您可以使用BIND_AUTO_CREATE标志绑定服务,如果服务未启动,它将启动。但是,当您解除绑定服务时,服务将被销毁
  • 带有0标志的bindService始终返回true
  • 您可以随时致电startService。如果服务已在运行,则不会创建新服务。将调用正在运行的服务onstart命令

  • 如果在onCreate中启动服务,然后在onResume中启动bindService,并在onPause中取消绑定服务,那么应该不会有任何问题

    我认为这也是有问题的,因为如果用户按下返回键,您的活动就会被破坏。在我们的音乐播放器示例中,我们希望在用户点击“播放”后,音乐继续播放,即使他们确实按了“后退”。只要您不调用stopService,您的音乐应该继续播放,但下次显示活动时,
    startService()
    将从
    onCreate()
    调用,我们又回到了同一个问题上。我不太明白你的问题。据我所知,您想知道服务是否正在运行。你为什么想知道?您在调用startService时是否向该服务传递了一个意图?很抱歉,您太迟钝了。在一定程度上,我试图理解安卓服务系统应该如何工作。我试图编辑这个问题,以提及我的具体问题。我不完全理解这是如何工作的,但可能会对您有所帮助。