【攻克Android (27)】四大组件之 Service

一、Service

1.概念

Service是Android系统的后台服务组件,适用于开发无界面、长时间运行的应用功能。例如音乐播放等。

Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。

2.特点

(1)没有用户界面,有利于降低系统资源消耗。

(2)比Activity的优先级高,不会轻易被Android系统终止。

(3)即使Service被系统终止,在系统资源恢复后Service也将自动恢复运行状态。

(4)用于进程间通信(InterProcessCommunication,IPC),

解决两个不同Android应用程序进程之间的调用和通讯问题。

3.Service生命周期及其回调函数

【攻克Android (27)】四大组件之 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。

相关推荐