Service基础用法
服务(service)是一种可在后台执行长时间操作而不提供界面的应用组件,由应用的组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。服务默认运行在其托管进程的主线程中,因此如果需要在服务中执行耗时或者阻断性操作,需要使用单独的线程或者使用系统提供的IntentService
。一般情况下,如果需要执行的任务只有在用户与应用交互时才需要执行,则首先应考虑使用线程,而不是服务。
服务的类型
- 前台服务,前台服务可以用来执行一些用户能注意到的操作,例如播放音乐,前台服务必须显示
通知
,即使用户停止与应用的交互,前台服务仍会继续运行。 - 后台服务,用来执行用户不会直接注意到的操作,例如压缩清理应用缓存。
- 绑定服务,当应用组件通过
bindService
绑定到服务时,服务即处于绑定状态,绑定服务会提供C/S接口与应用组件进行通信,一个服务可以同时被多个组件绑定,当全部取消绑定后,服务才会被销毁。
创建并使用服务
可以通过创建 Service
的子类来使用服务,在子类中需要实现一些方法来处理服务的生命周期,一般情况下需要重写以下方法:
方法名 | 描述 |
---|---|
onCreate | 首次创建服务时,系统会(在调用 onStartCommand() 或 onBind() 之前)调用此方法来执行一次性设置程序。如果服务已在运行,则不会调用此方法。 |
onBind | 当另一个组件想要与服务绑定(例如执行 RPC)时,系统会通过调用 bindService() 来调用此方法。在此方法的实现中,必须通过返回 IBinder 提供一个接口,以供客户端用来与服务进行通信。如果并不希望服务被绑定,可以直接返回 null。 |
onUnbind | 所有与当前服务绑定的客户端调用了解绑方法后调用 |
onStartCommand | 当另一个组件(如 Activity)请求启动服务时,系统会通过调用 startService() 来调用此方法。执行此方法时,服务即会启动并可在后台无限期运行。如果实现了此方法,则在服务工作完成后,需通过调用 stopSelf() 或 stopService() 来停止服务。(如果只想提供绑定,则无需实现此方法。) |
onDestory | 当不再使用服务且准备将其销毁时,系统会调用此方法。服务应通过实现此方法来清理任何资源,如线程、注册的侦听器、接收器等。这是服务接收的最后一个调用。 |
通常可以扩展以下两个类来创建启动服务
- Service,这是所有服务的基类,默认运行在应用的主线程中,需要自己创建并维护工作线程。
class CustomService:Service() {
private val TAG = "CustomService"
override fun onCreate() {
Log.d(TAG, "onCreate")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent?): IBinder? {
Log.d(TAG, "onBind")
return null
}
override fun onDestroy() {
Log.d(TAG, "onBind")
super.onDestroy()
}
}
- IntentService,这是Service的子类,内部维护了一个工作线程(HandlerThread)通过队列的方式串行的处理所有启动请求(onStartCommand方法),将其转发到
onHandleIntent
方法,提供了onBind
的默认实现返回null,一般情况下更推荐使用此类来使用服务。例如:
class CustomIntentService(private val name: String) : IntentService(name) {
private val TAG = "CustomIntentService"
override fun onHandleIntent(intent: Intent?) {
Log.d(TAG, "onHandleIntent")
}
}
服务的生命周期
service_lifecycle.png由上图可见,服务的生命周期,主要有两种情况:
-
启动服务,由其他组件调用
image.pngstartService
创建,然后无限期运行,可以通过服务自己调用stopSelf()
或者其他组件通过调用stopService
来停止服务,服务停止后,系统会将其销毁。
-
绑定服务,有其他组件(客户端)调用
image.pngbindService
创建,客户端可通过IBinder
接口与服务进行通信,通过调用unbindService
关闭连接,多个客户端可绑定相同的服务,在所有客户端解绑之前,调用stopSelf()
和stopService
实际不会停止服务。
-
启动&绑定 混合使用,当一个服务同时被启动和绑定时,单独的停止服务和解绑操作都不会使服务停止,必须所有客户端解绑和停止服务的方法被调用两个条件都满足服务才会停止。
image.png
网友评论