Service基础|青训营笔记
这是我参与[第四届青训营]笔记创作活动的第3天
前言
本文所写的是本人的个人见解,如有错误或者不恰当之处,欢迎私信我,加以改正!
本文将从什么是Service,service生命周期,两种service使用方式
1.什么是Service
Service是一个四大组件之一,可以在后台执行长时间运行的操作。它不提供用户界面。一旦启动,服务可能会继续运行一段时间,即使在用户切换到另一个应用程序之后也是如此。此外,组件可以绑定到服务以与其交互,甚至执行进程间通信 (IPC)
官方解释是围绕着service不是什么:
- Service不是一个单独的进程。Service对象本身并不意味着它正在自己的进程中运行;除非另有指定,否则它将在与它所属的应用程序相同的进程中运行。
- Service不是线程。它本身不是在主线程之外完成工作的手段(以避免应用程序无响应错误)
因此Service的主要作用有两个方面:
- 应用程序可以告诉系统它想要在后台执行的操作(即使用户不直接与应用程序交互)。这对应于对
context.startService()的调用,该调用要求系统安排service的工作,直到service或其他人显式停止它为止。 - 应用程序向其他应用程序公开其某些功能的工具。这对应于对
Context.bindService()的调用,它允许与service建立长期连接,以便与service进行交互。
2.Service的生命周期
了解Service之后,接下来就介绍一下service的生命周期⬇️
由上面的内容可以知道service的是有两种类型:
- StartService()启动service(启动后运行)
- BindService()启动service(需绑定后运行)
常用方法
onStartCommand()
startService()当另一个组件请求启动服务时,系统通过调用此方法来调用此方法。当这个方法执行时,服务就会启动并且可以无限期地在后台运行。如果您实现了这一点,您有责任在服务完成时通过调用stopSelf()或停止服务stopService()。如果您只想提供绑定,则不需要实现此方法。
onBind()
bindService()当另一个组件要与服务绑定时,系统会通过调用该方法来调用该方法。在此方法的实现中,您必须提供一个接口,客户端使用该接口通过返回一个IBinder. 您必须始终实现此方法;但是,如果您不想允许绑定,则应返回 null。
onCreate()
onStartCommand()系统在最初创建服务时(在调用或 之前)调用此方法来执行一次性设置过程 onBind()。如果服务已在运行,则不调用此方法。
onDestroy()
当服务不再使用并且正在被销毁时,系统会调用此方法。您的服务应该实现它以清理任何资源,例如线程、注册的侦听器或接收器。这是服务收到的最后一个调用。
3.Service使用方式
- StartService()启动service(启动后运行)
首次启动会创建一个service实例,根据其生命周期来看,依次调用onCreate()和onStartCommand()方法,此时Service进入运行状态,如果再次调用StartService启动service,将不再创建新的service对象,系统将直接调用前面已创建的service对象,调用其onStartCommand()方法,也因此可以说它不受调用者的生命周期限制,只要不调用stopService方法那么service就会一直运行。
接下来我们创建一个项目去测试一下service的生命周期吧,首先我们在activity中创建两个按钮,之后创建一个startService类去继承service就行,代码如下
class StartService : Service() {
private val TAG:String = "StartServiceLearn"
//创建Service时调用
override fun onCreate() {
Log.d(TAG, "onCreate " + javaClass.simpleName)
super.onCreate()
}
//销毁Service时调用
override fun onDestroy() {
Log.d(TAG, "onDestroy " + javaClass.simpleName)
super.onDestroy()
}
//必须实现的一个方法,若为Startservice则返回为null就行
override fun onBind(intent: Intent?): IBinder? {
Log.d(TAG, "onBind " +javaClass.simpleName)
return null
}
//接收intent
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand " + javaClass.simpleName)
return super.onStartCommand(intent, flags, startId)
}
override fun onUnbind(intent: Intent?): Boolean {
Log.d(TAG, "onUnbind: " + javaClass.simpleName)
return super.onUnbind(intent)
}
override fun onRebind(intent: Intent?) {
Log.d(TAG, "onRebind: "+ javaClass.simpleName)
super.onRebind(intent)
}
}
运行情况如下
如果我多次启动那又会怎样
由上图可知多次启动并不会重新创建而是调用其onStartCommand方法,当我们点击停止服务(调用stopService方法)service就会被销毁。
那么大家可以多试试,思考一下如果我不停止startservice,直接返回上一个activity,此时服务的生命周期发生变化吗❓(其实并不会)
- BindService()启动service(需绑定后运行)
首次使用bindService绑定service对象是,系统会实例化一个service对象,并调用onCreate和onBind方法,然后调用者就利用binder和service进行交互,如果再次调用bindService去绑定service,系统不会创建新的service实例,也不再调用onBind,只会直接把binder对象传递给后来的进程,如果我们解除与服务的绑定只需调用unbindservice(),之后会调用onUnbind(),如果此时只绑定了多个进程,那么只有与所有的进程解除了绑定后,系统才会调用onDestory()方法来销毁service,或者所绑定的进程被销毁了,那么service对象也会终止
接下来,我们在原有项目的基础上,再创建一个BindService类,看看绑定服务的生命周期跟启动服务有什么区别,代码如下
class BindService : Service() {
private val binder:IBinder = MyBinder()
private val TAG:String = "BindServiceLearn"
//通信匿名类
class MyBinder : Binder() {
fun startBinder(){
Log.d("BindServiceLearn", "MyBinder 中的 startBinder: ")
}
fun stopBinder(){
Log.d("BindServiceLearn", "MyBinder 中的 stopBinder ")
}
}
//绑定
override fun onBind(intent: Intent?): IBinder? {
Log.d(TAG, "onBind: "+ javaClass.simpleName)
return binder
}
//创建Service时调用
override fun onCreate() {
Log.d(TAG, "onCreate: "+javaClass.simpleName)
super.onCreate()
}
//销毁Service时调用
override fun onDestroy() {
Log.d(TAG, "onDestroy: " + javaClass.simpleName)
super.onDestroy()
}
//解绑service时调用
override fun onUnbind(intent: Intent?): Boolean {
Log.d(TAG, "onUnbind: " + javaClass.simpleName)
return super.onUnbind(intent)
}
//在BindService中不调用
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand: "+ javaClass.simpleName)
return super.onStartCommand(intent, flags, startId)
}
override fun onRebind(intent: Intent?) {
Log.d(TAG, "onRebind: " + javaClass.simpleName)
super.onRebind(intent)
}
}
运行情况如下
如果我进行多次绑定又会如何:没有变化
思考一下如果我选择返回上一个activity不进行解绑操作那会发生什么,直接帮我们调用onUnbind和onDestroy方法
注意:每一个service都需要在Androidmanifest.xml中注册
<service android:name=".StartService"/>