-
onStartCommand方法,返回START_STICKY
-
提升Service优先级
在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = “1000”这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。 -
提升Service进程优先级,比如改为前台进程
Android中将进程分成6个等级,由高到低分别是:前台进程、可视进程、次要服务进程、后台进程、内容供应节点以及空进程。当系统进程空间紧张时,会按照优先级自动进行进程回收。
1.可以使用startForeground()将服务设置为前台进程。
startForeground(1,notification);
在onDestory中记得stopForeground(true);
2.另外一种方法 开启一个像素的Activity https://www.jianshu.com/p/4ab34e6d3e5f -
在onDestory中重启Service
直接重新启动,或发送广播,由receiver来启动 -
监听系统广播来启动Service
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.PACKAGE_RESTARTED" />
-
双进程守护 和 使用JobService(SDK>=21)
https://www.cnblogs.com/xinmengwuheng/p/7070113.html
这两个是推荐方法,JobService轻量级一些,适合一般的需求 -
守护进程(以下转,部分room 有后台保护进程功能)
使用Jni,在 c端 fork进程,检测Service是否存活,若Service已被杀死,则进行重启Service. 至于检测方式,可以轮询获取子进程Pid,若为1, 则说明子进程被Init进程所领养,已经成为了孤儿进程. 但是这种方式比较消耗电量,并且由于不同手机系统定制的改变,当应用被强制停止时,父进程并不一定被真正杀死,因此在一些特定机型上是无法通过此方式进行判断. 这里推荐使用liunx socket的方式进行类似心跳包的检测,并且当触发检测Service是否被杀死之前,需要判断应用是否已经被卸载,如果应用已经被卸载,则不再进行检测Service行为,直接调用exit(0)退出子进程,避免浪费系统资源和消耗电量.
可参照:https://github.com/CharonChui/DaemonService注意: 目前在Android 5.0系统上会把fork出来的进程放到一个进程组里, 当程序主进程挂掉后,也会把整个进程组杀掉,因此用fork的方式也无法在Android5.0及以上系统实现守护进程. 这个是系统层面的限制,当然也是为了优化整个的系统环境,守护进程给手机带来的体验并不好
具体见源码:
http://androidxref.com/5.0.0_r2/xref/frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java补:Android5.0 以上目前已有人使用黑科技攻克,部分机型可能无法起到作用,但思路很值得借鉴,代码结构也不错, 具体方案见:https://github.com/Marswin/MarsDaemon
native进程方式最大缺点是费电,原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环或定时器,轮训判断主进程是否存活,当主进程不存活时进行拉活。
其次5.0以上系统不支持。但是JobSheduler可以替代在Android5.0以上native进程方式,这种方式即使用户强制关闭,也能被拉起来,亲测可行。 -
几个需要root系统的方法
1.将应用编译为系统应用
2.android:persistent=“true”
网友评论