Service(服务):是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。
Service的种类:
(1) 按运行地点分类:本地服务(Local Service)和远程服务(Remote Service)
本地服务(Local Service),该服务依附在主进程上,优点是服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL。缺点是主进程被Kill后,服务便会终止。应用场景,音乐播放器播放等不需要常驻的服务。
远程服务(Remote Service),该服务是独立的进程,优点是服务为独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。缺点是该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。应用场景,一些提供系统服务的Service,这种Service是常驻的。
(2) 按运行类型分类:前台服务和后台服务
前台服务,会在通知栏显示的 Notification,当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用。常见的如音乐播放服务。
后台服务,默认的服务即为后台服务,不会在通知一栏显示 的 Notification。当服务被终止的时候,用户是看不到效果的。某些不需要运行或终止提示的服务,如天气更新,日期同步,邮件同步等。
配置服务:Service也是四大组件之一,所以必须在manifests中配置
Service的两种状态:启动状态和绑定状态
启动状态:当应用组件(如 Activity)通过调用 startService() 启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响,除非手动调用才能停止服务, 已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。
绑定状态:当应用组件通过调用 bindService() 绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。 仅当与另一个应用组件绑定时,绑定服务才会运行。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。
启动Service的两种方式:startService方法和bindService方法
(1) startService方法:第一步、定义一个类继承Service。第二步、在AndroidManifest.xml文件中配置该Service。第三步、使用Context的startService(Intent)方法启动该Service。第四步、不再使用该Service时,调用Context的stopService(Intent)方法停止该Service。
(2) bindService方法:第一步、创建BinderService服务端,继承自Service并在类中创建一个实现IBinder接口的实现实例对象并提供公共方法给客户端调用。第二步、从onBind()回调方法返回此Binder实例。第三步、在客户端中,从onServiceConnected回调方法接收Binder,并使用提供的方法调用绑定服务。
Service的生命周期状态:
onCreate(): 首次创建服务时,系统将调用此方法。如果服务已在运行,则不会调用此方法,该方法只调用一次。
onStartCommand(): 当另一个组件通过调用startService()请求启动服务时,系统将调用此方法。
onDestroy(): 当服务不再使用且将被销毁时,系统将调用此方法。
onBind(): 当另一个组件通过调用bindService()与服务绑定时,系统将调用此方法。
onUnbind(): 当另一个组件通过调用unbindService()与服务解绑时,系统将调用此方法。
onRebind(): 当旧的组件与服务解绑后,另一个新的组件与服务绑定,onUnbind()返回true时,系统将调用此方法。
Service的生命周期方法:
startService():启动Service服务 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand() 如果一个service被startService多次启动,onCreate()只会调用一次 onStartCommand()调用次数=startService()次数。
stopService():关闭Service服务 手动调用stopService()后,自动调用内部方法:onDestory() 如果一个service被启动且被绑定,如果没有在绑定的前提下stopService()是无法停止服务的。
bindService():绑定Service服务 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()。
unbindService():解绑Service服务 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()。
注意事项:
(1) startService()和stopService()只能开启和关闭Service,无法操作Service;bindService()和unbindService()可以操作Service。
(2) startService开启的Service,调用者退出后Service仍然存在;BindService开启的Service,调用者退出后,Service随着调用者销毁。
(3) 在调用 bindService 绑定到Service的时候,应当保证在某处调用 unbindService 解除绑定(尽管 Activity 被 finish 的时候绑定会自动解除,并且Service会自动停止)。
(4) 注意使用 startService启动服务之后,一定要使用stopService停止服务,不管你是否使用bindService。
(5) 同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;
(6) 当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
(7) 在sdk 2.0及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。
寄语:希望的事,迟早会实现,但实现的希望,总是变了味的。——杨绛《干校六记》
举报/反馈