绑定到一个Service

  应用组件(客户端)可以调用bindService()绑定到一个service.Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder.

  绑定是异步的.bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,客户端必须创建一个ServiceConnection的实例并传给bindService().ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder.

注:只有activities,services,和contentproviders可以绑定到一个service—你不能从一个broadcastreceiver绑定到service.

所以,从你的客户端绑定到一个service,你必须:

1实现ServiceConnection.

你的实现必须重写两个回调方法:

onServiceConnected()

系统调用这个来传送在service的onBind()中返回的IBinder.

OnServiceDisconnected()

Android系统在同service的连接意外丢失时调用这个.比如当service崩溃了或被强杀了.当客户端解除绑定时,这个方法不会被调用.

2调用bindService(),传给它ServiceConnection的实现.

3当系统调用你的onServiceConnected()方法时,你就可以使用接口定义的方法们开始调用service了.

4要与service断开连接,调用unbindService().

  当你的客户端被销毁,它将从service解除绑定,但是你必须总是在你完成与service的交互时或当你的activity暂停于是service在不被使用时可以关闭此两种情况下解除绑定.(下面会讨论更多在适当的时候绑定和解除绑定的问题.)

  例如,下面是前一篇"派生Binder类"中创建的代码片段,它把客户端连接到了service.所有需要做的就是把返回的IBinder强制转换到LocalBinder类并且请求LocalService实例:
  

LocalService mService;  private ServiceConnection mConnection = new ServiceConnection() {      // 当与service的连接建立后被调用     public void onServiceConnected(ComponentName className, IBinder service) {          // Because we have bound to an explicit         // service that is running in our own process, we can         // cast its IBinder to a concrete class and directly access it.         LocalBinder binder = (LocalBinder) service;          mService = binder.getService();          mBound = true;      }      // 当与service的连接意外断开时被调用     public void onServiceDisconnected(ComponentName className) {          Log.e(TAG, "onServiceDisconnected");          mBound = false;      }  };  

使用这个ServiceConnection,客户端可以绑定到一个service,通过把它传给bindService().例如:

Intentintent = new Intent(this, LocalService.class);

bindService(intent,mConnection, Context.BIND_AUTO_CREATE);

第一个bindService()的参数是一个明确指定了要绑定的service的Intent.

第二个参数是ServiceConnection对象.

第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可.

补充事项
下面是一些关于绑定到service的重要事项:

你总是需要捕获DeadObjectException异常.它会在连接被打断时抛出.这是被远程方法抛出的唯一异常.

对象引用计数是跨进程的作用的.

你应该在客户端的生命期内使绑定和解除绑定配对进行,例如:

如果你需要在你的activity可见时与service交互,你应该在onStart()绑定并在onStop()中解除绑定.

如果你想让你的activity即使在它停止时也能接收回应,那么你可以在onCreate()中绑定并在onDestroy()中解除绑定.注意这意味着你的activity需要使用在自己整个运行期间使用service(即使位于后台),所以如果service在另一个进程中,那么你增加了这个进程的负担而使它变得更容易被系统杀掉.

  注:你一般不应该在你的activity的onResume()和onPause()中绑定和解除绑定到service,因为这些回调方法,出现在每个生命期变化中,并且你需要使发生在这些变化中的处理最小化.还有,如果你应用中的多个activity绑定到同一个service,并且有一个变化发生在其中两个activity之间,service可能在当前activity解除绑定(pause中)和下一个绑定前(rusume中)被销毁又重建.

管理BoundService的生命期
  当一个service的所有客户端都解除绑定,Android系统就销毁它(除非它是从onStartCommand()启动).如果你的service是一个纯boundservice,你不需管理它的生命期—Android系统会为你管理它.

  然而,如果你选择了实现onStartCommand()回调方法,那么你必须明确地停止service,因为service现在被认为是"开始的".在此情况下,service会一直运行,直到service使用stopSelf()停止它自己或另外的组件调用了stopService()停止了它,不管是否有客户端绑定了它.

  另外,如果你的service已经启动并且接受绑定,那么当系统调用你的onUnbind()方法,你可以选择返回true表示你想在客户端下一次绑定到service时接受一个对onRebind()的调用(而不是一个对onBind()的调用).onRebind()返回void,但是客户端依然会在它的onServiceConnected()回调中接收到IBinder.下图演示了这种生命其的逻辑:

更多相关文章

  1. Android(安卓)Studio使用注解式框架Butterknife教程
  2. TeleMCU视频会议之Android版本WebRTC 客户端支持
  3. DataBinding使用指南(三):生成的binding类
  4. Android(安卓)SurfaceFlinger 学习之路(二)----SurfaceFlinger概
  5. 如何启用Service,如何停用Service。
  6. 移动架构39_RxAndroid二(变换调用:map、flatMap、lift、compose)
  7. Android(安卓)Service组件的生命周期及用法总结
  8. listview与adapter用法
  9. Android(安卓)自定义 dialog

随机推荐

  1. Android整机调试串口新玩法
  2. Android动态修改ListView中指定Item的组
  3. Android(安卓)Studio--低版本如何不使用A
  4. Android(安卓)8.0 EditText 焦点无法移动
  5. Android中的对象序列化方法
  6. [Android] 基于 Linux 命令行构建 Androi
  7. Android获得线性渐变某点的颜色
  8. Android、iOS 将有Edge浏览器 Win10又一
  9. android ORM框架LitePal完全解析(crud)
  10. h5页面引用idangerous.swiper.js 插件兼