Android Service全解(二)之 bindService(转)
前面已经介绍了的start是开启Service的一种方式,绑定(bind)Service是开启Service的另一种方法,而且绑定Service几乎可以被认为是专门为IPC(进程间交互)准备的。绑定Serivce是通过Context.bindService()方法实现的,bindService和startService有一定的区别,首先就反应在生命周期上。bindService不会回调onStart()/onStartCommand()方法,而会回调onBind()方法;Service要停止绑定则需要要调用unbindService()方法,而不用stopService()或者stopSelf()方法。
可以看下官方文档上bindService()方法的原型及部分参数说明:
1 /**
2 * bindService
3 *
4 * @param service
5 * 用显示的组件名(Class<?>方式)或者逻辑描述(action等)
6 * 的Service的Intent
7 * @param conn
8 * 在Service开启或停止时接收信息的组件
9 * @param flags
10 * 绑定选项,可以是0,BIND_AUTO_CREATE,BIND_DEBUG_UNBIND,
11 * BIND_NOT_FOREGROUND,BIND_ABOVE_CLIENT,
12 * BIND_ALLOW_OOM_MANAGEMENT或者BIND_WAIVE_PRIORITY
13 * @return 绑定成功为true,否则为false
14 */
15 public abstract boolean bindService(Intent service, ServiceConnection conn,
16 int flags);
Service的绑定方法bindService()中除了用了Service的Intent外,还使用到了ServiceConnection对象,这个对象除了可以为Service绑定者(caller)回调方法,还是解绑定(unbind)时需要提供的参数。bindService()方法中最后一个参数flag则是表明绑定Service时的一些设置,一般情况下可以直接使用0,有关这个问题将在本系列文章以后的内容中介绍。
android.content.ServiceConnection是一个接口,实现(implementate)这个接口有2个方法需要重写(Override)。一个是当Service成功绑定后会被回调的onServiceConnected()方法,另一个是当Service解绑定或者Service被关闭时被回调的onServiceDisconnected()。前者(onServiceConnected()方法)会传入一个IBinder对象参数,这个IBinder对象就是在Service的生命周期回调方法的onBind()方法中的返回值,它对Service的绑定式IPC起到非常重要的作用,有关绑定式IPC的内容将在本系列文章后面的内容中详细介绍。
使用Context.ubindService()方法之后,Service的生命周期回调onUnbind()会被调用。如果所有bind过Service的组件都调用unbindService()方法之后,Service会被停止,其onDestroy()回调会被调用,除非Service在未停止之前使用startService()方法开启过Service,这部分内容在本系列文章前面的内容已经介绍过。
以下代码是bindService()及unbindService()的惯常用法:
1 // declare/define ServiceConnection object which is recommended to be global
2 ServiceConnection conn;
3
4 // bind
5 bindService(new Intent(this, MyService.class),
6 conn = new ServiceConnection() {
7
8 public void onServiceDisconnected(ComponentName name) {
9 // will be invoked when service is disconnected
10 }
11
12 public void onServiceConnected(ComponentName name,
13 IBinder service) {
14 // will be invoked when service is connected
15 }
16 }, 0);
17
18 // unbind
19 unbindService(conn);
需要注意的是,onServiceDisconnected()方法在Service被显示的(explicitly)unbind或者被停止时都会被回调。比如,当Android系统资源(主要是RAM)严重不足时,Service是很有可能被结束(kill)掉的,如果被kill掉,则onServiceDisconnected()方法会被回调,但这个时候Service是没有走完所有的生命周期的(比如不会回调onDestroy()方法)。当然,无论Service的开启是使用bind还是start,一旦当系统资源恢复之后,这些被kill掉的Service会以可能的最短的时间内被系统自动恢复(重新进行新的生命周期,从回调onCreate()方法开始)。
官方文档提到说bindService()方法不能在BroadcastReceiver组件中调用,关于这个问题也会在以后关于BroadcastReceiver的内容中介绍。