Service介绍
- Service简介
- Service特性
- Service生命周期
- Service的2种启动方式
- IntentService
Service简介
理解Android的Service,可以从以下几个方面来理解:
- Service是在main Thread中执行,Service中不能执行耗时操作(网络请求,拷贝数据库,大文件)。
- 可以在xml中设置Service所在的进程,让Service在另外的进程中执行。
- Service执行的操作最多是20s,BroadcastReceiver是10s,Activity是5s。
- Activity通过bindService(Intent,ServiceConnection,flag)与Service绑定。
- Activity可以通过startService和bindService启动Service。
Service特性
- Service 的粘性: 当 Service 被意外终止(非正常停止,即不是通过 stopService() 或 stopSelf() 停止)后,会在未来的某一刻自动重启。 Service 的粘性是通过 onStartCommand() 方法的返回值确定的,可用的值有: —– Service.START_REDELIVER_INTENT -----> 粘性的,且在自动重启时,会重新给Service发送Intent对象。 —– Service.START_STICKY -----> 粘性的 —– Service.START_NOT_STICKY -----> 非粘性的 —– Service.START_STICKY_COMPATIBILITY -----> 粘性的,并且兼容的 当需要 Service 是非粘性的,取值 Service.START_NOT_STICKY;当需要 Service 是粘性的,并且还需要获取 Intent 对象时,取值 Service.START_REDELIVER_INTENT;否则,只是需要粘性的,不需要 Intent 时,取值super.onStartCommand() 默认值。
- Service 是单例的,在程序中一个 Service 类只会存在一个对象
- Service 是没有界面的,适合于在后台进行耗时操作,但要注意 Service 仍然是运行在主线程中的,故耗时的操作还是需要开启子线程来进行。
Service生命周期
代码语言:javascript复制/*Service 启动方式有两种
一种是通过startService()方式进行启动
另一种是通过bindService()方式进行启动。不同的启动方式他们的生命周期是不一样.
*/
通过startService()这种方式启动的service,生命周期是这样:
调用startService() → onCreate()→ onStartCommand()→ onDestroy()
这种方式启动的话,需要注意一下几个问题,第一:当我们通过startService被调用以后,多次在调用startService(),onCreate()方法也只会被调用一次,而onStartConmon()会被多次调用当我们调用stopService()的时候,onDestroy()就会被调用,从而销毁服务。第二:当我们通过startService启动时候,通过intent传值,在onStartConmon()方法中获取值的时候,一定要先判断intent是否为null。
通过bindService()方式进行绑定,这种方式绑定service,生命周期走法:
bindService() → onCreate() → onBind() → onUnBind() → onDestroy()
bingService这种方式进行启动service好处是更加便利activity中操作service,比如加入service中有几个方法,a,b ,如果要在activity中调用,在需要在activity获取ServiceConnection对象,通过ServiceConnection来获取service中内部类的类对象,然后通过这个类对象就可以调用类中的方法,当然这个类需要继承Binder对象
onCreate():首次创建服务时,系统将调用此方法。如果服务已在运行,则不会调用此方法,该方法只调用一次。
onStartCommand():当另一个组件通过调用startService()请求启动服务时,系统将调用此方法。
onDestroy():当服务不再使用且将被销毁时,系统将调用此方法。
onBind():当另一个组件通过调用bindService()与服务绑定时,系统将调用此方法。
onUnbind():当另一个组件通过调用unbindService()与服务解绑时,系统将调用此方法。
onRebind():当旧的组件与服务解绑后,另一个新的组件与服务绑定,onUnbind()返回true时,系统将调用此方法。
Service的2种启动方式
第一种启动方式: 通过 start 方式开启服务,即 startService(启动)。started(启动):当应用程序组件(如 activity)调用 startService() 方法启动服务时,服务处于 started 状态。 使用 service 的步骤:
- 义一个类继承 service
- manifest.xml 文件中配置 service
- 使用 context 的 startService(Intent) 方法启动 service
- 当不在使用时,调用 stopService(Intent) 方法停止服务。
使用 start 方式启动的生命周期:onCreate() – > onStartCommand() – > onDestory() 注意: 如果服务已经开启,不会重复回调 onCreate() 方法,如果再次调用 context.startService() 方法,service 而是会调用onStart() 或者 onStartCommand() 方法。停止服务需要调用 context.stopService() 方法,服务停止的时候回调 onDestory 被销毁。 特点: 一旦服务开启就跟调用者(开启者)没有任何关系了。开启者退出了,开启者挂了,服务还在后台长期的运行,开启者不能调用服务里面的方法。
第二种启动方式: 采用 bind 的方式开启服务,即 bindService(绑定服务)。bound(绑定):当应用程序组件调用 bindService() 方法绑定到服务时,服务处于 bound 状态。 使用 service 的步骤:
- 定义一个类继承 Service
- 在 manifest.xml 文件中注册 service
- 使用 context 的 bindService(Intent, ServiceConnection, int) 方法启动 service
- 不再使用时,调用 unbindService(ServiceConnection) 方法停止该服务。
使用这种 bind 方式启动的 service 的生命周期如下:onCreate() – > onBind() --> onUnbind() – > onDestory() 注意: 绑定服务不会调用 onStart() 或者 onStartCommand() 方法 特点: bind 的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。绑定者可以调用服务里面的方法。
IntentService
IntentService是一个抽象类,继承自Service,内部存在一个ServiceHandler(Handler)和HandlerThread(Thread)。IntentService是处理异步请求的一个类,在IntentService中有一个工作线程(HandlerThread)来处理耗时操作,启动IntentService的方式和普通的一样,不过当执行完任务之后,IntentService会自动停止。另外可以多次启动IntentService,每一个耗时操作都会以工作队列的形式在IntentService的onHandleIntent回调中执行,并且每次执行一个工作线程。IntentService的本质是:封装了一个HandlerThread和Handler的异步框架。