【Creating a Bound Service】
一个绑定service允许组件通过bindService()绑定它,为了建立一个长期存在的连接(通常不允许组件使用startService()启动)。
你应该建立一个绑定的service当你希望和service交互从activity或你应用程序的其它组件或者暴露应用程序的功能给其它应用程序,通过IPC。
为了创建一个绑定service,你必须实现onBind()回调方法来返回一个IBinder,定义了和service的交互接口。其它应用程序组件能调bindService()来取得接口,然后开始调用service中的方法。service存活于为其它组件服务,即绑定时,所以当没有组件绑定service时,系统摧毁它(你不需要关闭一个绑定的service你启动Started Service一样)
为了建立一个绑定的service,第一件事你必须做的是定义一个客户怎样同service交互的接口。这个接口在service和客户之间必须是一个IBinder的子类,也是你的service返回给onBind()回调的方法。一旦这个客户收到IBinder,它可以开始交互和这个service使用这个接口。
多个客户能一次绑定到service。当一个客户完成和service交互,它调用unbindService()来解绑定。一旦没有客户绑定到service,系统摧毁这个service。
有许多种方法实现一个绑定service,实现比started service更复杂。
【Sending Notifications to the User】
一旦运行,一个service能通知用户事件使用ToastNotifications或Status Bar Notifications。
一个toast notification是一种消息,出现在当前窗口表面一段时间然后消息,一个status bar notification一个图标在状态条和一条消息,用户可以选择为了操作(例如启动一个activity)。
通常,一个status bar notification是最好的技术当一些背景工作完成(例如一个文件下载完成),用户可以现在就执行他。当用户选择通知从扩展的view,这个notification可以启动一个activity(例如查看下载)。
【Running a Service in the Foreground】
一个前景service是用户感知到的,不是系统在低内存下会杀死的service。一个前景service必须为状态条提供一个通知,在“Ongoing”头下,意味着notification不能被忽视除非service要么停止或从前景移除。
例如,一个音乐播放器从service播放音乐,应该被设置运行在前景,因为用户显式察觉到它的运行。状态条的notification可以指定当前的歌曲,允许用户启动一个activity来和音乐播放器交互。
为了请求你的service运行有前景,调用startForeground()。这个方法花费两个参数:一个整数惟一标识notification和状态条Notification。例如:
为了移除这个service从前景,调用stopForeground()。这个方法花费两个boolean,指定是否移除status bar notification。这个方法不停止service。可是,如果你停止service当它仍然运行在前景,那么notification也会被移除。
注意:startForeground()和stopForeground()函数在Android 2.0(API Level 5)引入。为了运行你的服务在前景在老版本平台上,你必须使用setForeground()方法。
【Managing the Lifecycle of a Service】
一个service的生命周期比activity简单多了。可是,却要更重视你service被创建和销毁,因为一个service可以运行在后台没有用户察觉到。
service生命周期--什么时候被创建、什么时候被销毁--有两条路径:
1、A started serviceservice创建当一个组件调用 startService()。然后service永久运行,必须停止它自己通过stopSelf()。另一个组件也能停止这个service通过stopService()。当service停止 ,系统销毁它。
2、A bound serviceservice被创建当另一个组件调用bindService()。客户然可通过IBinder和service通信。客户可以关闭连接通过unbindService()。多个客户能绑定到同一个service并且当他们所有都反绑定了,系统摧毁这个service()。(service不需要自我关闭)
这两条路径不是完全隔离。也就是,你可以绑定一个service已经用startService()启动。例如,一个背景音乐service能被创建通过startService()通过Intent指定音乐来播放。稍后,可能当用户希望体验一些操作在播放器上或获取当前音乐信息,一个activity可以绑定到service通过bindService()。在这种情况下,stopService()或stopSelf()不能真正停止service直到所有的客户都停止 。
【Implementing the lifecycle callbacks】
就像activity,一个service有生命周期回调方法,你可以实现来监视service的状态变化以及执行工作在合适的时机。下面的service框架陈述每个生命周期方法:
注意:和activity生命周期回调函数不一样,你不需要调用父类实现当实现这些函数的时候。
通过实现这些方法,你可以监听两个嵌套的service生周周期循环:
一个service的整个生命周期在onCreate()和onDestroy()间在。和activity一样,一个service像它初始工作在onCreate,以及释放所有的维护资源在onDestroy()。例如,一个音乐 播放器能创建线程音乐将在onCreate()中播放,然后停止线程在onDestroy()中。
一个activity的service生命周期以onStartCommand()或onBind()开始。每个方法被Intent处理,被传递到startService()或bindService()分别的。
注意:虽然一个started service被stopSelf或stopService()停止,没有一个service各自的回调函数(没有onStop()回调)。所以,除非service被绑定到一个client,这个系统摧毁它当service被停止--onDestroy()是惟一的回调接收器。