最近我的项目要实现这样一个成果:运行后,要有一个service始终保持在后盾运行,不论用户作出什么操作,都要保障service不被kill,这可真是一个难题。参考了现今各种定制版的零碎和平安厂商牛虻软件,如何能保障本人的Service不被杀死呢?

其实除了惯例的伎俩,咱们能够参考一下微信和360,设置-程序-正在运行,能够看到微信是同时开启了两个过程和服务:

【有趣味能够钻研一下 守护过程 和 AIDL 】

我猜测它应该是互相监听,如果有一方被kill掉,另一个捕捉到立刻启动,以达到service永远都在运行的状态,貌似360也是这个原理,具体是不是这个样子,还有待参考,目前我还没有参透网站监控它们是如何实现的,先简略说一下我本人的防控措施吧,首先介绍一下Service概念,忘性不好,反复造一下车轮,高手能够间接看最初。

Service是在一段不定的工夫运行在后盾,不和用户交互利用组件。每个Service必须在manifest中 通过<service>来申明。能够通过contect.startservice和contect.bindserverice来启动。和其余的利用组件一样,运行在过程的主线程中。这就是说如果service须要很多耗时或者阻塞的操作,须要在其子线程中实现(或者用零碎提供的IntentService,它继承了Service,它解决数据是用本身新开的线程)。【当然你也能够在新的线程中startService,这样Service就不是在MainThread了】

本地服务 Local Service 用于应用程序外部

它能够启动并运行,直至有人进行了它或它本人进行。在这种形式下,它以调用Context.startService()启动,而以调用Context.stopService()完结。它能够调用Service.stopSelf() 或 Service.stopSelfResult()来本人进行。不管调用了多少次startService()办法,你只须要调用一次stopService()来进行服务。

【用于实现应用程序本人的一些耗时工作,比方查问降级信息,并不占用应用程序比方Activity所属线程,而是单开线程后盾执行,这样用户体验比拟好】

近程服务 Remote Service 用于android零碎外部的应用程序之间

它能够通过本人定义并裸露进去的接口进行程序操作。客户端建设一个到服务对象的连贯,并通过那个连贯来调用服务。连贯以调用Context.bindService()办法建设,以调用 Context.unbindService()敞开。多个客户端能够绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。

【可被其余应用程序复用,比方天气预报服务,其余应用程序不须要再写这样的服务,调用已有的即可】

以startService()启动服务,零碎将通过传入的Intent在底层搜寻相干合乎Intent外面信息的service。如果服务没有启动则先运行onCreate,而后运行onStartCommand (可在外面解决启动时传过来的Intent和其余参数),直到显著调用stopService或者stopSelf才将进行Service。无论运行startService多少次,只有调用一次stopService或者stopSelf,Service都会进行。应用stopSelf(int)办法能够保障在解决好intent后再进行。onStartCommand ,在2.0后被引入用于service的启动函数,2.0之前为public void onStart(Intent intent, int startId) 。

以bindService()办法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。onBind()只有采纳Context.bindService()办法启动服务时才会回调该办法。该办法在调用者与服务绑定时被调用,当调用者与服务曾经绑定,屡次调用Context.bindService()办法并不会导致该办法被屡次调用。采纳Context.bindService()办法启动服务时只能调用onUnbind()办法解除调用者与服务解除,服务完结时会调用onDestroy()办法。

3,领有service的过程具备较高的优先级

官网文档通知咱们,Android零碎会尽量放弃领有service的过程运行,只有在该service曾经被启动(start)或者客户端连贯(bindService)到它。当内存不足时,须要放弃,领有service的过程具备较高的优先级。

1. 如果service正在调用onCreate,onStartCommand或者onDestory办法,那么用于以后service的过程则变为前台过程以防止被killed。
2. 如果以后service曾经被启动(start),领有它的过程则比那些用户可见的过程优先级低一些,然而比那些不可见的过程更重要,这就意味着service个别不会被killed.
3. 如果客户端曾经连贯到service (bindService),那么领有Service的过程则领有最高的优先级,能够认为service是可见的。
4. 如果service能够应用startForeground(int, Notification)办法来将service设置为前台状态,那么零碎就认为是对用户可见的,并不会在内存不足时killed。
5. 如果有其余的利用组件作为Service,Activity等运行在雷同的过程中,那么将会减少该过程的重要性。

保障service不被杀掉

StartCommond几个常量参数简介:

1、START_STICKY

在运行onStartCommand后service过程被kill后,那将保留在开始状态,然而不保留那些传入的intent。不久后service就会再次尝试从新创立,因为保留在开始状态,在创立service后将保障调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。

2、START_NOT_STICKY

在运行onStartCommand后service过程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的显著的办法(startService)调用才从新创立。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接管到任何null的intent。

3、START_REDELIVER_INTENT在运行onStartCommand后service过程被kill后,零碎将会再次启动service,并传入最初一个intent给onstartCommand。直到调用stopSelf(int)才进行传递intent。如果在被kill后还有未解决好的intent,那被kill后服务还是会主动启动。因而onstartCommand不会接管到任何null的intent。

public int onStartCommand(Intent intent, int flags, int startId) {

flags = START_STICKY;

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

}

晋升service优先级(未胜利)

在AndroidManifest.xml文件中对于intent-filter能够通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时实用于播送。

Android中的过程是托管的,当零碎过程空间缓和的时候,会按照优先级主动进行过程的回收。Android将过程分为6个等级,它们按优先级程序由高到低顺次是:

1.前台过程( FOREGROUND_APP)
2.可视过程(VISIBLE_APP )

  1. 主要服务过程(SECONDARY_SERVER )

4.后盾过程 (HIDDEN_APP)
5.内容供给节点(CONTENT_PROVIDER)
6.空过程(EMPTY_APP)

当service运行在低内存的环境时,将会kill掉一些存在的过程。因而过程的优先级将会很重要,能够应用startForeground 将service放到前台状态。这样在低内存时被kill的几率会低一些。