我应该何时使用unbindService(),如何正确使用它来解除使用AIDL接口的远程服务的绑定?

时间:2011-07-11 02:35:29

标签: java android service aidl

我正在编写一个简单的音乐播放器,我创建了一个播放服务,它实现了一个AIDL接口来与客户端绑定,一个是简单的跟踪浏览器,另一个是更简单的玩家活动。该服务控制MediaPlayer对象,而两个活动使用ServiceConnections获取与服务的连接。

这包含在两个活动的onStart()方法中:

@Override
public void onStart()
{
  super.onStart();
  Intent i = new Intent(this, PureService.class);
  startService(i);
  bindService(i, mConnection, 0);
}

我这样做是为了在取消绑定后服务不会立即停止。当然,这实际上并不是一个问题,因为我的活动完全拒绝与服务解除绑定。无论何时我的应用程序在这些活动中都进入unbindService,unbindService每次都会抛出IllegalArgumentException,毫无例外(呵呵)。

在onStop方法中:

@Override
public void onStop()
{
  super.onStop();

  if (mBound) {
    try {
      unbindService(mConnection);
    } catch (java.lang.IllegalArgumentException e)
    {
      //Print to log or make toast that it failed
    }
  }
  mBound = false;
}

我想知道的是:

  • 我应该在onStop()方法中调用unbindService()吗?或者根本没有?
  • 我是否正确称呼它?
  • 我开始/绑定我应该知道的服务的方式有什么特别之处吗?
  • 我是在做一些完全错误的事情吗?我是Android编程的新手,所以这肯定不是不可能的。

提前致谢。

编辑:以下是ServiceConnection覆盖

public void onServiceConnected(ComponentName className, IBinder service) {
  mBound = true;
  mService = IPureService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName arg0) {
  mBound = false;
}

播放器活动中还有一些额外的代码,但它与绑定本身无关。

3 个答案:

答案 0 :(得分:4)

首先,除非您确实需要跨进程调用此服务(即,从其他.apks,或者您正在使用android:process将您自己的.apk由于某种原因拆分为多个进程),然后我真的建议只是放弃使用aidl。没有收益就更复杂了。服务文档中的“本地服务示例”显示了如何执行此操作:http://developer.android.com/reference/android/app/Service.html

其次,在开始的同时进行绑定是设计中一些基本缺陷的强烈迹象。启动服务和绑定到服务在语义上是非常不同的,因此将基于这些不同的语义在不同的地方完成。也就是说,如果两者都完成了......事实上,这是一个不寻常的情况,你使用start和bind来使用相同的服务。

在用于进行音乐播放的服务的类实现中,它将在主动执行回放时使用start(因此当用户不再主动与应用程序的UI交互时,其进程不会被系统杀死) 。当用户进入UI时启动服务可能会导致痛苦,因为现在服务的启动/停止状态没有明确定义 - 它可以启动,因为它正在进行回放或者因为用户碰巧已经进入应用程序的用户界面,现在什么时候才能停止它?这会很麻烦。

现在只要取消绑定 - 你只需要确保始终将unbindService()与之前的bindService()匹配。从你的代码片段看起来你正在这样做,但有一些奇怪的东西,比如mBound永远不会被设置。事实上,如果你一直在onStart()中绑定并在onStop()中解除绑定,你永远不需要有一个mBound来决定是否取消绑定,因为onStop()总是在onStart()之后被调用。

因此,使用此处提供的代码,看起来不会出现问题。但是,如果您遇到异常,那么显然可能是您应用中的其他位置。为了帮助缩小问题范围,可以在调用bindService()时使用此标志,以便在发生故障时在日志中获取其他信息:http://developer.android.com/reference/android/content/Context.html#BIND_DEBUG_UNBIND

答案 1 :(得分:0)

有几点:

  1. 如果您希望自己的服务的续航时间超过受约束的活动,请START_STICKY返回onStartCommand
  2. onStop中的unbindService()很好:这是我在多个应用程序中调用它的地方,我从未见过这个特定的错误。我希望您的ServiceConnection还有其他一些问题:显示mConnection对象的代码,我们可能会发现它有什么问题。

答案 2 :(得分:0)

我也有这个奇怪的错误。然后我尝试在onResume()而不是在Activity中的onStart()中对服务进行绑定,瞧,没有更多例外!我仍然有点无能为力。如果有人可以解释,我会成为一个快乐的程序员。 :)