4

我正在编写一个简单的音乐播放器,并创建了一个播放服务,它实现了一个 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;
}

玩家活动中有一些额外的代码,但它与绑定本身无关。

4

3 回答 3

4

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

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

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

现在至于何时解除绑定——您只需要确保始终将 unbindService() 与先前的 bindService() 匹配。从您的代码片段来看,您似乎正在这样做,但其中有一些奇怪的事情,例如从未设置过 mBound。事实上,如果您始终在 onStart() 中绑定并在 onStop() 中取消绑定,则永远不需要 mBound 来决定是否取消绑定,因为 onStop() 总是在 onStart() 之后调用。

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

于 2011-07-11T03:06:28.437 回答
0

几点:

  1. 如果您希望您的服务比绑定的活动寿命更长,请在onStartCommand中返回START_STICKY 。
  2. unbindService() inonStop很好:这是我在多个应用程序中调用它的地方,我从未见过那个特定的错误。我希望您的 ServiceConnection 有其他问题:显示您的mConnection对象的代码,我们可能会弄清楚它有什么问题。
于 2011-07-11T03:05:56.603 回答
0

我也有这个奇怪的错误。然后我尝试在 onResume() 中而不是在 Activity 中的 onStart() 中绑定服务,瞧,没有更多的例外!我仍然有点不知道为什么会这样。如果有人可以解释,我会是一个快乐的编码员。:)

于 2012-03-14T08:03:23.390 回答