温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android基础(七) – Service 保活

发布时间:2020-07-03 03:07:05 来源:网络 阅读:2197 作者:lm8751 栏目:移动开发

总结:大部分应用只需做1-2-3 步即,如业务要求比较高 可适当采用4.

1.修改onStartCommand函数返回值为START_STICKY。(资源紧张情况下 系统杀掉Service后会恢复,进入恢复队列)(建议采用)

@Override

publicintonStartCommand(Intent intent,intflags,intstartId) {

    return  START_STICKY;

   //return super.onStartCommand(intent, flags, startId);

}

 2.提升service的优先级,设置android:priority=”1000″(建议采用)

<service

android:name=”…”

android:exported =”false”>

<!– 1000是最高优先级,数字越小,优先级越低 –>

<intent-filter android:priority=”1000″/>

</service>

 3.提升service进程优先级,为前台进程  (建议采用)
          步骤一:新建前台Service (复制可用)

public class BootstrapService extends Service {
@Override public void onCreate() { super.onCreate(); startForeground(this); // 自己关闭自己 清除notification stopSelf(); }
@Override public void onDestroy() { super.onDestroy(); stopForeground(true); }
public static void startForeground(Service context) { NotificationManager nm = (NotificationManager)context. getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(context); builder.setContentTitle(“I’m running”) .setContentText(“”) .setWhen(System.currentTimeMillis()) .setPriority(Notification.PRIORITY_MIN) .setSmallIcon(R.drawable.notification_icon) .setAutoCancel(true); Notification notification = builder.build(); context.startForeground(8888, notification); } }
步骤二:在主Service 2次调用
public class MainService extends Service {
@Override public void onCreate() { super.onCreate();
//第一次设置前台进程 BootstrapService.startForeground(this); //第二次设置前台进程 为了清除notification Intent intent = new Intent(this, BootstrapService.class); startService(intent); }
@Override public void onDestroy() { super.onDestroy(); stopForeground(true); } }
4.守护进程(以下转,部分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/Proce***ecord.java

补:

Android5.0 以上目前已有人使用黑科技攻克,部分机型可能无法起到作用,但思路很值得借鉴,代码结构也不错, 具体方案见:

https://github.com/Marswin/MarsDaemon

5.复写Service onDestory()方法,重启服务。(如进程杀死无效)
6.android:persistent=“true” (需root权限才有效 ,基本无实际应用价值)
7.通过监听系统广播来把自己拉起来 (4.4系统以上 应用退出后 将不再接受系统广播 ,实际效果不明显)

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI