Service是一段不定的时间运行在后台、不和用户交互的应用组件,每个Service必须在manifest中通过<service>来声明,通过contect.startservice和contect.bindservice来启动。
生命周期:Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,需要注意的是,如果Service已经启动了,当我们再次启动service时,不会再执行onCreate()方法,而是直接执行onStart()方法。
Service和其他的应用组件一样,运行在进程的主线程中,这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现,但是Service不能自己运行,需要通过其他方法来启动服务,service有两种启动模式(startService()/bindService()不是完全分离的):
1、本地服务Local Service用于应用程序内部。它可以启动运行,直至人为停止它或者它自己停止,在这种方式下,它以调用Context.startService()或Service.stopSelfResult()来自己停止,不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。它可以用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
函数原型:
public abstract ComponentName startService(Intent service)
通过函数的原型我们可以看出是一个Component去调用,参数就是一个intent,在该intent中去指定一些规则和消息来启动符合条件的Service。当client端发出去Intent去启动Service端时,component调用startService(Intent intent)启动Service,Service端通过onstartCommand(Intent,int,int)函数来做出相应,下面对onstartCommand(Intent,int,int)进行详细说明:
函数原型:
public int onStartCommand(Intent intent,int flags,int startId)
Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值,从Android官方文档中,说明了onStartCommand有4种返回值:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
该函数不能人为的去直接调用,而是由Android system在Service的main thread中由系统去调用,所以一般情况下继承Service的子类都要重写Service类的:onCreate();onStartCommand(),onBinder(),onStart(),onDestroy(),onRebind(),onUnbind()方法,然后再在函数中编写其他自己想要实现的功能,
所以通过context.startService(Intent intent)来启动Service时的过程为: startService()-->onCreate()-->onStart();
当关闭服务的时候Service端处理过程为: destroystopService()-->onDestroy()-->Service stop
2、远程服务Remote Service用于android系统内部的应用程序之间。它可以通过自己定义并暴漏出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调整服务。连接以调用Context.bindService()方法建立,以调用Context.unbindService()关闭,多个客户端可以绑定至同一个服务,如果服务此时还没有加载,bindService()会先加载它。可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
函数原型;
public boolean bindService(Intent service,ServiceConnection conn,int flags)
参数说明:intent是client端定义的参数,和startService中的intent作用一样;
conn是一个ServiceConnection实例,ServiceConnection是一个public interface,一个用于监视app service状态的Interface,必须去实现ServiceConnention的两个抽象函数,我们可以通过onServiceConnected(ComponentName name,IBinder service)和onServiceDisconnected(ComponentName name)这两个函数来决定连接或者断开Service;
flags:绑定操作选项;
返回值:绑定成功返回true,失败返回false
绑定一个运行的Service。可以创建一个即使运行的又是绑定的Service,也就是通过startService()来让这个Service运行,然后client端通过bindService()来绑定到Service,那么当Service启动后系统不会为所有客户端解除绑定unBindService()后销毁service,而是,你必须通过调用stopSelf()或stopService()显示地停止这个Service,多个client可以同时连接到一个service,当第一个Client绑定到Service的时候Service的onBinder()方法才接受到IBinder,之后Service将把同一个IBinder传递给其他的client,之后其他Client的连接service就不再会调用自身的onBind()方法了,当最后一个client取消绑定到Service时,系统就会销毁这个Service。
这个模式开启service过程为:bindService-->onCreate()-->onBind()-->Service running;
关闭service过程为:onUnBind()-->onDestroy()-->Service stop
该模式下在Service每一次开启关闭过程中,只有onStart()可被多次调用(通过多次startService调用),其他onCreate(),onBind(),onUnbind(),onDestroy()在一个生命周期中只能被调用一次。
Android API资料对Service两种模式过程描述图