继承关系
Context -> ContextWrapper -> Service 位于 android.app 包中
一、生命周期
onCreate():首次创建服务时调用,该方法只调用一次。
onStartCommand():当另一个组件通过调用startService()请求启动服务时,系统将调用此方法。
onDestroy():当服务不再使用且将被销毁时,系统将调用此方法。
onBind():当调用bindService()与服务绑定时,调用此方法。
onUnbind():当调用unbindService()与服务解绑时,调用此方法。
onRebind():当旧的组件与服务解绑后,另一个新的组件与服务绑定,onUnbind()返回true时,系统将调用此方法。
参考:https://www.jianshu.com/p/cc25fbb5c0b3
二、重要属性
android:enabled=[“true” | “false”]
是否可实例化,默认true 。如设置false ,Service将不可用
android:exported=[“true” |”false”]
是否允许跨进程调用,默认值跟filter是否有子元素有关,filter子元素个数为0,默认值为false ,否则true
android:permission=”string”
调用此Service需要的权限,可自定义权限增加Service安全。如没设置,此Service就没权限要求。
android:process=”:String”
给Service指定运行的进程。未设置默认为应用主进程。如设置,
首字母大写 代表此新进程为本应用私有进程,其它应用不可访问。
首字母小写 代表此进程为全局进程(公共),其它应用可访问
android:isolatedProcess=[“true” | “false”]
如果设置为true,这个服务将运行在专门的进程中,这个进程从系统的剩余部分独立出来,它自身没有权限。同它唯一的通信方式就是通过这个Service API(binding或starting)。
三、启动方式
1.StartService 同一个Service Start多次,onCreate()执行一次,onStartCommand()执行多次
2.BindService 同一个Service bind多次, onCreate()执行一次,onBind()也执行一次
生命周期调用
1)启动Service服务
单次:startService() —> onCreate() —> onStartCommand()
多次:startService() —> onCreate() —> onStartCommand() —> onStartCommand()
2)停止Service服务
stopService() —> onDestroy()
3)绑定Service服务
bindService() —> onCreate() —> onBind()
4)解绑Service服务
unbindService() —> onUnbind() —> onDestroy()
5)启动绑定Service服务
startService() —> onCreate() —> onStartCommand() —> bindService() —> onBind()
6)解绑停止Service服务
unbindService() —> onUnbind()
stopService() —> onDestroy()
当同时使用startService与bindService的Service关闭需unbindService与stopService同时调用(调用顺序无所谓),才能终止Service.
7)解绑绑定Service服务
unbindService() —> onUnbind(ture) —> bindService() —> onRebind()
Service关闭方法
1.stopSelf();
2.stopSelfResult();
3.stopService()
四、进程保活
1、关键2点
提高进程的优先级
在进程被kill之后能够唤醒
2、进程优先级划分
1.前台进程 (Foreground process)
2.可见进程 (Visible process)
3.服务进程 (Service process)
4.后台进程 (Background process)
5.空进程 (Empty process)
这是一种粗略的划分,进程其实有一种具体的数值,称作oom_adj,注意:数值越大优先级越低
3、提高进程的优先级
配置文件提升Service优先级和app系统级别
<service
android:name=”…”
android:exported =”false”
android:persistent=”true” //提升应用到系统级
/>
<intent-filter android:priority=”1000″/>//提高优先级 1000是最高优先级,数字越小,优先级越低
</service>
切后台 -> 弹通知
隐藏通知栏iocn
对于 API level < 18 :调用startForeground(ID, new Notification()),发送空的Notification ,图标则不会显示。
对于18 <= API level <25:在需要提优先级的service A启动一个InnerService,两个服务同时startForeground,且绑定同样的 ID。Stop 掉InnerService ,这样通知栏图标即被移除。
参考:https://blog.csdn.net/xutao123111/article/details/78994383
8.0上述方案无效,会显示”有一个应用正在后台使用” ,想要去除,官方建议使用JetPack-WorkManager https://www.jianshu.com/p/de19752f159c
锁屏 -> 弹1像素界面
注册广播监听锁屏和解锁事件, 锁屏后启动一个1像素的透明Activity,这样直接把进程的oom_adj数值降低到0,0是android进程的最高优先级。 解锁后销毁这个透明Activity
4、进程被kill
系统内存不足杀死情况
在onStartCommand()返回值修改为START_STICKY,在onDestory重启(不保证100%重启成功)
Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内 Service 被杀死达到5次,则系统不再拉起。
进程被取得 Root 权限的管理工具或系统工具通过 forestop 停止掉,无法重启。
用户手动使用手机自带清理工具和第三方app(360,猎豹清理大师等)
引导用户添加手机白名单
其它
依赖push、第3方应用唤醒、厂家白名单等
备注:
对于Android6.0以及以下的大部分机型还是有效果的,但是Android7.0和Android8.0基本上所有机型全部阵亡,大部分后台进程在锁屏后无法存活超过20分钟
测试结果显示,oppo/vivo这两家厂商进程保活最困难,小米和三星比较宽松。其他的机型居中。
参考
https://www.jianshu.com/p/53c4d8303e19
https://blog.csdn.net/qq_37199105/article/details/81224842
五.其它
1. bindService和startService区别
生命周期不同 bindService -> onBind() startService->onStartCommand(),
方法调用次数不同 多次startService onStartCommand会执行多次 ,而bindService只会指定一次
关闭服务 bindService开启服务以后,与activity存在关联,退出时必须调用unbindService方法,否则会报ServiceConnection泄漏的错误。而Service不用。
2.IntentService
优点:
省去在 Service 中手动开线程的麻烦
当操作完成时,我们不用手动停止 Service
原理 (单线程HandlerThread 队列串行处理)
IntentService采用Handler & HandlerThread方式
所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求
可启动 IntentService 多次,而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。
IntentService 会自动停止,而不需要我们去手动控制
参考:https://www.jianshu.com/p/5a32226d2ce0
3.Service 与Thread、Application的区别
Thread Service Application
是否可设置独立进程 否 是 否
是否能管理生命周期 否 是 是
是否能与其它组件通信 较麻烦 较易 一般
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。