Service简介及启动方式

Service的简介

Service并不是一个进程也不是一个线程,它本身实际上非常简单的,主要提供两个功能:

  • 应用程序告诉系统在后台处理一些事情,甚至不需要用户同应用程序直接交互,系统主要是通过Context.startService()来启动服务的,除非Service本身或者其他人明确来停止它否则将一直运行下去。
  • 将应用程序自己的某些功能暴露给其它程序,这种交互主要通过Context.bindService(),允许长连接的服务来与之交互。

Service事实上也是运行在主线程中的,因此如果处理cpu密集工作,还是建议在service开启一个新的子线程的。

Service的生命周期

service

Service的生命周期虽然并不像Activity那样复杂,但是它有两种模(startService()/bindService()不是完全分离的),多数情况下这两种模式是混合使用的。上面左图是用startService()创建的Service的生命周期,右图是用bindService()创建的Service的生命周期。

Context.startService()方式启动

启动时,startService –>onCreate() -> onStart()

停止时,stopService -> onDestory()

Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()或者stopSelf()方法结束服务,服务结束时会调用onDestroy()方法。如果调用者直接退出而没有停止Service,则Service 会一直在后台运行。

这种启动模式是唯一可以在手机的正在运行的服务或者管理应用程序中正在运行一栏明确看得到的服务。

Context.bindService()方式启动

绑定时,bindService -> onCreate() -> onBind()

调用者退出了,即解绑定时,Srevice就会unbindService ->onUnbind() -> onDestory()

用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()–>onDestroy()方法。

该种模式主线程Activity主要通过一个长连接来同Service进行交互,代码执行顺序
bindService -> onCreate() -> onBind()—> onServiceConnected()

但是在解绑的时候onServiceDisconnected()放过并不会调用,我们查看Google官方文档描述,该方法只在Service 被破坏了或者被杀死的时候调用. 例如, 系统资源不足, 要关闭一些Services, 刚好连接绑定的 Service 是被关闭者之一, 这个时候onServiceDisconnected() 就会被调用。

startForeground和stopForeground

一般服务都是运行在后台的,但是如果调用了startForeground()方法,那么我们的服务就是一个前台进程,就更不容易被系统回收杀死。public final void startForeground (int id, Notification notification)该方法需要传入一个Notification,事实上也很容易理解,服务运行在后台,那么我们怎么知道它到底在干什么呢,发个通知就可以了,比如我们在开始播放音乐时,系统往前台发送一个消息告诉你正在播放的音乐信息,当音乐播放停止是通知中也会有相应的标示来提示用户。相应的当想要关闭音乐播放器的时候我们可以调用stopForeground(true)就可以了,前台的通知就会自动销毁。

service_02

结束语及相关代码

两种模式有以下几点不同之处:startService模式下调用者与服务无必然联系,即使调用者结束了自己的生命周期,只要没有使用stopService方法停止这个服务,服务仍会运行;通常情况下,bindService模式下服务是与调用者生死与共的,在绑定结束之后,一旦调用者被销毁,服务也就立即终止,不求同生,但愿同死。

One comment

发表评论