一、概述
Service是Android四大组件之一,是一段长生命周期但是没有用户界面的组件,用来做播放音乐、监控状态之类的后台操作,也可以将应用的某种功能暴露给其他程序。
二、生命周期
官方给出的Service生命周期如下:
我们先来看各种回调方法的含义:
-
onCreate():
首次创建服务的时候,系统将调用此方法。若服务已经开启,则不会再回调,只执行一次。
-
onStartCommand():
当组件通过调用
startService()
启动Service时回调方法。 -
onBind():
当组件通过调用bindService()
与Service绑定时回调方法。 -
onUnbind():
当组件通过调用unbindService()
与Service解绑时回调方法。 -
onDestroy():
当Service销毁时回调方法。
从上图我们可以知道Service有两种方法可以启动,而这两种方法也可以穿插着进行,下面我们通过输出来直观地看一看,代码如下:
MainActivity:
class MainActivity : AppCompatActivity() {
private val TAG = "ITestServiceTag"
private val serviceConnection = object :ServiceConnection{
override fun onServiceDisconnected(name: ComponentName?) {
Log.d(TAG,"执行方法----onServiceDisconnected()")
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
Log.d(TAG,"执行方法----onServiceConnected()")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this,ITestService::class.java)
startService.setOnClickListener {
Log.d(TAG,"点击按钮----startService")
startService(intent)
}
stopService.setOnClickListener{
Log.d(TAG,"点击按钮----stopService")
stopService(intent)
}
bindService.setOnClickListener {
Log.d(TAG,"点击按钮----bindService")
bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
}
unBindService.setOnClickListener {
Log.d(TAG,"点击按钮----unBindService")
unbindService(serviceConnection)
}
}
}
ITestService:
class ITestService : Service() {
private val TAG = "ITestServiceTag"
override fun onBind(intent: Intent?): IBinder? {
Log.d(TAG,"执行方法----onbind()")
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG,"执行方法----onStartCommand()")
return super.onStartCommand(intent, flags, startId)
}
override fun onCreate() {
super.onCreate()
Log.d(TAG,"执行方法----onCreate()")
}
override fun onUnbind(intent: Intent?): Boolean {
Log.d(TAG,"执行方法----onUnbind()")
return super.onUnbind(intent)
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG,"执行方法----onDestroy()")
}
}
输出结果如下:
-
startService()
—>bindService()
—>stopService()
—>unbindService()
-
bindService()
—>startService()
—>unbindService()
—>stopService()
从上面两个结果我们可以知道,当Service通过调用bindService()
方法处于绑定状态时,调用stopService()
方法不会结束Service,而是等到Service解除绑定状态后才会将Service结束并销毁。
通过以上介绍及结果,我们可以得出以下结论:
a. startService()
—>…—>stopService()
:
onCreate()
—>onStartCommand()
—>…—>onDestroy()
b. bindService()
—>unbindService()
:
onCreate()
—>onBind()
—>onUnBind()
—>onDestroy()
c. startService()
—> bindService()
—> stopService()
—> unbindService()
:
onCreate()
—>onStartCommand()
—>onBind()
—>onUnBind()
—>onDestroy()
三、Activity和Service交互
Activity传递数据到Service最主要且最方便就是通过Intent来实现,在这里我们不做赘述,主要说一说Service如何向Activity传递数据。
1. 通过Binder
经过上面的讲解,我们知道创建一个Service的时候,都必须实现onBind()
方法的,该方法会返回一个IBinder类型的对象,IBinder是Android进程间通信的核心部分,在这里,他也可以用来进行进程内通信。在onBind
方法中返回的IBinder对象,会作为调用bindService(Intent service, ServiceConnection conn,int flags)
方法时,ServiceConnection接口下onServiceConnected(ComponentName name, IBinder service)
方法的参数返回。
下面我们用一个简单的例子实现一下:
ITestService:
class ITestService : Service() {
private val TAG = "ITestServiceTag"
override fun onBind(intent: Intent?): IBinder? {
return ITestBinder()
}
fun showMsg() {
Toast.makeText(this, "回调成功$TAG", Toast.LENGTH_LONG).show()
}
inner class ITestBinder : Binder() {
var iTestService = this@ITestService
fun showMsg() {
iTestService.showMsg()
}
}
}
MainActivity:
class MainActivity : AppCompatActivity() {
private var binderService: ITestService.ITestBinder? = null
private val serviceConnection = object :ServiceConnection{
override fun onServiceDisconnected(name: ComponentName?) {
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binderService = service as ITestService.ITestBinder?
binderService?.showMsg()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this,ITestService::class.java)
bindService.setOnClickListener {
bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
}
unBindService.setOnClickListener {
unbindService(serviceConnection)
}
}
}
在onBind()
方法中返回的IBinder对象主要是为了能够让组件获取到Service对象,从而可以调用Service里面的回调方法和变量。
2. 通过Broadcast广播
这种方法较为复杂,需要在Activity中创建一个BroadcastReceiver,在Service中发送广播。
ITestService:
class ITestService : Service() {
override fun onBind(intent: Intent?): IBinder? {
val intent = Intent()
intent.action = "location.itest"
sendBroadcast(intent)
return null
}
}
MainActivity:
class MainActivity : AppCompatActivity() {
private val iTestBroadcast = ITestBroadcast()
private val serviceConnection = object :ServiceConnection{
override fun onServiceDisconnected(name: ComponentName?) {
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//注册广播
val filter = IntentFilter("location.itest")
registerReceiver(iTestBroadcast,filter)
val intent = Intent(this,ITestService::class.java)
bindService.setOnClickListener {
bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE)
}
unBindService.setOnClickListener {
unbindService(serviceConnection)
}
}
inner class ITestBroadcast : BroadcastReceiver(){
private val TAG = "ITestServiceTag"
override fun onReceive(context: Context?, intent: Intent?) {
val intentAction = intent?.action
if (intentAction == "location.itestr") {
Toast.makeText(this@MainActivity,"成功回调$TAG",Toast.LENGTH_LONG).show()
}
}
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(iTestBroadcast)
}
}
网友评论