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的内容中介绍。