我问的是一个令人烦恼的问题,该问题已经(在我看来部分地)得到解决here https://stackoverflow.com/questions/5243562/lifecycle-of-service-that-is-started-and-bound and here https://stackoverflow.com/questions/3514287/android-service-startservice-and-bindservice。假设像在许多示例中一样,我们想要创建一个音乐应用程序,使用(比如说)单个活动和服务。我们希望当 Activity 停止或销毁时服务能够持续存在。这种生命周期建议启动服务:
当应用程序组件(例如
Activity) 通过调用 startService() 来启动它。一旦启动,服务
可以无限期地在后台运行,即使该组件
开始它被摧毁
好的,但是我们还希望能够与服务通信,因此我们需要服务绑定。没问题,我们已经绑定并启动了服务这个答案表明 https://stackoverflow.com/questions/3514287/android-service-startservice-and-bindservice:
- 在活动启动时(或其他某个点),我们调用启动服务() http://developer.android.com/reference/android/content/Context.html#startService%28android.content.Intent%29
- 之后我们打电话绑定服务() http://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29以获得IBinder http://developer.android.com/reference/android/os/IBinder.html界面,然后从那里继续。
到目前为止一切顺利,但出现了一个问题,即当活动开始时,我们不知道服务是否存在。它可能已经开始,也可能没有开始。答案可能是这样的:
- 启动时,尝试绑定到服务(使用绑定服务() http://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29没有绑定_自动_创建 http://developer.android.com/reference/android/content/Context.html#BIND_AUTO_CREATE flag)
- 如果失败,则使用启动服务
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()
return true
即使服务没有运行?在这种情况下,该服务似乎尚未启动,基于Log
calls.
- 如果上一点是正确/预期的行为
bindService()
,是否有解决方法(即以某种方式确保startService
仅当服务未运行时才调用?)
附:我已经解决了我自己代码中的问题:我发出startService()
不管怎样,因为重复了startService()
就被简单地忽略了。不过,我还是想更好地理解这些问题。