【攻克Android (27)】四大组件之 Service
一、Service
1.概念
Service是Android系统的后台服务组件,适用于开发无界面、长时间运行的应用功能。例如音乐播放等。
Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
2.特点
(1)没有用户界面,有利于降低系统资源消耗。
(2)比Activity的优先级高,不会轻易被Android系统终止。
(3)即使Service被系统终止,在系统资源恢复后Service也将自动恢复运行状态。
(4)用于进程间通信(InterProcessCommunication,IPC),
解决两个不同Android应用程序进程之间的调用和通讯问题。
3.Service生命周期及其回调函数
3.1Service使用方式
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。
(1)启动方式
通过调用Context.startService()启动Service,通过调用Context.stopService()或Service.stopSelf()停止Service。
Service是由其他的组件启动的,但停止过程可以通过其他组件或自身完成。
如果仅以启动方式使用的Service,这个Service需要具备自管理的能力,且不需要通过函数调用向外部组件提供数据或功能。
(2)绑定方式
使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接。
通过bindService()函数绑定Servcie时,onCreate()函数和onBinde()函数将先后被调用。
通过unbindService()函数取消绑定Servcie时,onUnbind()函数将被调用,如果onUnbind()函数的返回true,则表示在调用者绑定新服务时,onRebind()函数将被调用。
(3)两种方式的区别
这两个方法都可以启动Service,但是它们的使用场合有所不同。
使用startService()方法启用服务,调用者与服务之间没有关联,即使调用者退出了,服务仍然运行。
使用bindService()方法启用服务,调用者与服务绑定在了一起,
调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
3.2Service生命周期回调方法
(1)启动方式中的回调方法
onCreate()、onStartCommand()、onDestroy()
onCreate()方法在服务被创建时调用,该方法只会被调用一次,
无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStartCommand()只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStartCommand()方法会被多次调用。
onDestroy()方法在服务被终止时调用。
(2)绑定方式中的回调方法
onCreate()、onBind()、onUnbind()、onDestroy()
onCreate()方法在服务被创建时调用,该方法只会被调用一次,
无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。
onDestroy()方法在服务被终止时调用。
3.3启动方式和绑定方式的结合
(1)如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下
onCreate()onStart()onBind()onUnbind()[重载后的方法需返回true]onRebind()
(2)结合的例子:
以MP3播放器为例,在后台的工作的Service通过Context.startService()启动某个特定音乐播放,但在播放过程中如果用户需要暂停音乐播放,则需要通过Context.bindService()获取服务链接和Service对象,进而通过调用Service的对象中的函数,暂停音乐播放过程,并保存相关信息。在这种情况下,如果调用Context.stopService()并不能够停止Service,需要在所有的服务链接关闭后,Service才能够真正的停止。
4.Service两种启动方式
(1)显式启动
在Intent中指明Service所在的类,并调用startService(Intent)函数启动Service。
(2)隐式启动
在注册Service时,声明Intent-filter的action属性。设置Intent的action属性,可以在不声明Service所在类的情况下启动服务。
(3)两种方式比较
若Service和调用服务的组件在同一个应用程序中,可以使用显式启动或隐式启动,显式启动更加易于使用,且代码简洁。
若服务和调用服务的组件在不同的应用程序中,则只能使用隐式启动。
5.Service的开发
服务的开发比较简单,如下:
第一步:继承Service类
public class SMSService extends Service { }
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行注册(不注册的话,这个Service根本无法启动):
<service android:name=".SMSService" />
使用<service>标签声明服务,其中的android:name表示的是Service的类名称,一定要与用户建立的Service类名称一致。
当在AndroidStudio中创建Service的时候,以上两步自动完成了。
6.Service分类
(1)本地服务与远程服务
Service分为本地服务(LocalService)和远程服务(RemoteService)。
1)本地服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源。另外,本地服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。主进程被Kill后,服务便会终止。
2)远程服务为独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务,具有较高的灵活性。该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。
(2)按使用方式分为以下三种:
1)startService启动的服务:主要用于启动一个服务执行后台任务,不进行通信。适用于服务和Activity之间没有调用交互的情况。停止服务使用stopService。
2)bindService启动的服务:该方法启动的服务可以进行通信。适用于服务和Activity相互之间需要方法调用或者传递参数。停止服务使用unbindService;
3)startService同时也bindService启动的服务:停止服务应同时使用unbindService与stopService。