Android基础-四大组件-Service

1,169 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

前言

最近项目在处理多进程的问题,发现很多关于Service的基础有点模糊了,而且近几个版本官方对Service做了很多限制调整,也没有及时整理,这里做一个简单的记录。

Service 简介

Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC)。例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互。

Service 分类

  • 前台服务:前台执行用户能注意的操作任务,即使用户停止与应用的交互,前台服务仍会继续运行。前台服务必须调用通知(Notification),让服务以显式的方式呈现给用户,如音乐播放等。
  • 后台服务:后台执行用户无法直接关注的操作任务,如业务计算等。在Android 8.0之后对其进行了相应的限制。
    • 应用进入后台之后,Service会持续运行数分钟,时间窗结束之后,应用会进入空闲状态,系统会停止应用的后台Service,服务调用stopSelf()
    • 系统不允许后台应用创建后台Service,但可以设置服务为前台服务,调用startForegroundService(),但需要注意5秒内需要调用 startForeground() 方法以显示新 Service 的用户可见通知。 如果应用在此时间限制内未调用 startForeground(),则系统将停止此 Service 并声明此应用为 ANR
  • 绑定服务:当应用组件通过调用 bindService() 绑定到服务时,服务即处于绑定状态。绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

Service使用

Service子类

class MultiProcessService: Service() {

    override fun onCreate() {
        super.onCreate()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}

** 清单文件**

  <service android:name=".MultiProcessService"
            android:exported="false"
  />

Service启动方式

startService方式

val intent = Intent(this, MultiProcessService::class.java)
startService(intent)
  • 当service首次启动,调用startService(intent)时,先回调onCreate(),再回调onStartCommand();如果不是首次启动,直接回调onStartCommand()
  • 当服务自身调用stopSelf()或者应用组件stopService()后,会执行onDestroy(),此时Service生命周期结束。

注意:无论调用多少次startService,服务都会回调onStartCommand(),只有首次实例化才会回调onCreate(),如果不调用stopSelf()或者stopService()服务都会一直存活。

bindService方式

这种方式相对会复杂一些,需要定义用以服务交互的IBinder对象和用以监控服务连接状态的ServiceConnection实现。

class MultiProcessService : Service() {
    override fun onBind(intent: Intent): IBinder =  MultiProcessBinder()
     inner class MultiProcessBinder : Binder() {
        //.....
    }
}

class MultiProcessActivity:Activity(){
    private val connection = object : ServiceConnection {
        override fun onServiceConnected(className: ComponentName, service: IBinder) {
           //当服务绑定成功后或中断后重启,服务会回调该方法
        }

        override fun onServiceDisconnected(arg0: ComponentName) {
            // 当服务异常终止时会调用。unbindService时不会调用
        }
    }
	override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val intent = Intent(this, MultiProcessService::class.java)
      	bindService(intent, connection, Context.BIND_AUTO_CREATE)
    }
}
  • 通过bindService方式绑定的Service,如果当前没有对象与Service绑定,Service生命周期结束,这个过程包括绑定对象被销毁,或者主动掉调用unbindService()

注意bindService()调用多次,如果组件与Service已经成功绑定后,不会多次返回ServiceConnection中的回调方法。

startService和bindService同时调用

两者可以同时启动Service,执行流程是按各自生命周期方法执行,需要注意的是这种情况下Service要回调onDestroy(),需要stopServiceunbindService分别执行。