四大组件:Service
Service有两种启动方式:StartService和bindService
- StartService
- 定义一个类继承service
- 在manifest.xml文件中配置该service
- 使用context的startService(intent)启动该service
- 不再使用时,调用stopService(Intent)或者stopSelf停止该服务
- bindService
- 创建bindService服务段,继承自service并在类中,创建一个实现binder接口的实例对象并提供公共方法给客户端调用
- 从onbind()回调方法返回此binder实例
- 在客户端中,从onserviceconnected()回调方法接收binder,并使用提供的方法调用绑定服务
Service的常见问题:
1. Service的保活?
调用Context.startService方式启动Service时,如果内存不足,Service会被回收
- 利用onStartCommand的返回值:START_STICKY,START_REDELIVER,onStartCommand的返回值有三个:
- START_NOT_STICKY: 销毁不重建,默认选项
- START_STICKY: 销毁并重建,Intent为null
- START_REDELIVER_INTENT:销毁并重建,Intent为最后一次保存值
- 利用onStartCommand的返回值:START_STICKY,START_REDELIVER,onStartCommand的返回值有三个:
- 提高Service的优先级
- 在AndroidManifest.xml文件中对于intent-filter可以通过android:priority =”1000”这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。
- 提高Service的优先级
- 提高Service进程的优先级
- 可以使用startForeground将service放到前台状态,这样低内存时,被杀死的概率会低一些。
- 提高Service进程的优先级
- 在onDestroy方法里重启Service
- 当service走到onDestroy()时,发送一个自定义广播,当收到广播时,重新启动service。
- 在onDestroy方法里重启Service
- 系统广播监听Service状态
- 将APK安装到/system/app,变身为系统级应用
2. 是否了解IntentService?
IntentService是Android提供的后台服务类,我们在外部组件中通过Intent向IntentService发送请求命令,之后IntentService逐个执行命令队列里的命令,接收到首个命令时,IntentService就开始启动并开始一条后台线程执行首个命令,接着队列里的命令将会被顺序执行,最后执行完队列的所有命令后,服务也随即停止并被销毁。
- 生命周期方法,同Service相同
- onCreate方法:在IntentService的onCreate方法中开启了一个异步线程HandlerThread来处理我们的请求,并利用Looper和Handler来管理我们的请求命令队列
- 停止服务:如果启动 IntentService 多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的 onHandleIntent 回调方法中执行,依次去执行,使用串行的方式,执行完自动结束。IntentService中的ServiceHandler的handleMassage中,每一次处理完数据之后都会调用stopSelf停止,该方法需要来自onStartCommand方法中的启动ID,只有在接收到最新的启动ID时才会停止服务,就是说,我们的IntentService直到命令队列中的所有命令被执行完后才会停止服务。
3. Service里面到底能不能执行耗时操作?
- 答案肯定是不能的,虽然Service定位是在后台执行长时间的操作,但是Service默认也是在主线程执行的,前面ANR讲过,前台服务执行超过20s就会ANR,平时你也许直接Service里面干过不算太久的耗时操作,并且看起来没什么事,那是因为后台服务ANR时间是200s。
- 正确做法是在Service内部开启子线程,或者直接只要IntentService。再者,在清单文件中显式给Service声明一个进程,注意不是线程。
4. stopSelf()与stopSelf(startId)的区别
每一次调用startService(),在onStartCommand()方法中,会产生一个startId,stopSelf()默认会传一个startId为-1,表示停止所有请求,会销毁服务,而stopSelf(startId)只会停止startId的这一次请求。上面IntentService中,每一次onHandleIntent()之后stopSelf(startId)停止当前请求,所有任务执行完后,才会销毁服务。