首页 文章

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

提问于
浏览
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()吗?或者根本不是?

  • 我是否正确称呼它?

  • 我开始/绑定我应该了解的服务的方式有什么特别之处吗?

  • 我完全做错了什么,完全错了吗?我当然不是不可能的 .

提前致谢 .

编辑:这是ServiceConnection覆盖

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

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

3 回答

  • 0

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

  • 4

    首先,除非您确实需要跨进程调用此服务(即,从其他.apks,或者您正在使用android:process将您自己的.apk由于某种原因拆分为多个进程),那么我真的建议只是放弃使用aidl . 没有收益就更复杂了 . 服务文档中的"Local Service Sample"显示了如何执行此操作: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

  • 0

    几点:

    • 如果您希望服务的生命周期超过绑定的活动,请在onStartCommand中返回START_STICKY .
      onStop 中的
    • unbindService()很好:这是我在多个应用程序中调用它的地方,我从未见过那个特定的错误 . 我希望您的ServiceConnection还有其他一些问题:显示 mConnection 对象的代码,我们可以弄清楚它有什么问题 .

相关问题