目录

  • 一、进程的一些基本常识
  • 二、如何保活
  • 三、如何拉活
  • 四、总结

一、进程的一些基本常识

Low Memory Killer

  • 系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。
  • 打开的应用越多,后台缓存的进程也越多。
  • 在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。

进程优先级

Android拉取项目后运行按钮置灰 android 进程拉活_保活


官网说明  何时杀死进程

  内存阈值在不同的手机上不一样,一旦低于该值,Android便会杀死对应优先级的进程,例如,当可用内存小于180MB(46080),就杀死空进程。

Android拉取项目后运行按钮置灰 android 进程拉活_进程保活拉活_02

上图中的数字分别对应为:

18432:前台进程大小
 23040:可见进程
 27648:服务进程
 32256:后台进程
 36864:contentProvider
 46060:空进程
阈值的单位是4KB


如何判断进程的优先级

  • 通过oom_adj值,判断进程的优先级
  • 不同手机的oom_adj 值可能不一样
  • 目标:值变低,优先级变高 

二、如何保活

1. Activity 1像素保活

原理: 手机关闭屏幕时,偷偷创建一个Activity,让应用成为前台进程;打开屏幕时,关闭该Activity。

缺点: 存在一个Activity不够干净。同时也需要在锁屏后才能提权。

Activity 1像素保活主要代码:

Android拉取项目后运行按钮置灰 android 进程拉活_进程保活拉活_03


Android拉取项目后运行按钮置灰 android 进程拉活_Android_04


Android拉取项目后运行按钮置灰 android 进程拉活_Android拉取项目后运行按钮置灰_05

2、前台 Service 保活
原理: 启动一个前台服务,从而拉高整个应用的优先级。

缺点: API >=26 后暂时没有方式能够隐藏通知

Android拉取项目后运行按钮置灰 android 进程拉活_优先级_06

三、如何拉活

1、广播拉活
  在发生特定系统事件时,系统会发出广播,通过在 AndroidManifest 中静态注册对应的广播监听器,即可在发生响应事件时拉活。
  但是从android 7.0开始,对广播进行了限制,而且在8.0更加严格https://developer.android.google.cn/about/versions/oreo/background.html#broadcasts
  可静态注册广播列表:
https://developer.android.google.cn/guide/components/broadcast-exceptions.html

“全家桶”拉活
  有多个app在用户设备上安装,只要开启其中一个就可以将其他的app也拉活。比如手机里装了手Q、QQ空间、兴趣部落等等,那么打开任意一个app后,其他的app也都会被唤醒。

2、Service系统机制拉活
START_STICKY:
  “粘性”。如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

START_NOT_STICKY:
  “非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

START_REDELIVER_INTENT:
  重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:
  START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

  只要 targetSdkVersion 不小于5,就默认是 START_STICKY。
  但是某些ROM 系统不会拉活。并且经过测试,Service 第一次被异常杀死后很快被重启,第二次会比第一次慢,第三次又会比前一次慢,一旦在短时间内 Service 被杀死4-5次,则系统不再拉起。


3、账户同步拉活

Android拉取项目后运行按钮置灰 android 进程拉活_优先级_07


Android拉取项目后运行按钮置灰 android 进程拉活_保活_08

  手机系统设置里会有Account帐户一项功能,任何第三方APP都可以通过此功能将我们自己的APP注册到这个Account帐户中,并且将数据在一定时间内同步到服务器中去。系统在将APP帐户同步时,自动将未启动的APP进程拉活,

Android拉取项目后运行按钮置灰 android 进程拉活_Android_09


系统账号同步机制拉活步骤:

  1. 继承Service并在内部继承实现用于返回Binder的AbstractAccountAuthenticator
  2. 在res/xml/文件夹下定义将要显示在Account列表的资源
  3. 在清单文件中配置AuthenticationService
  4. 创建App的账户
  5. 创建账户同步Service
  6. 告知系统我们的Account需要进行同步服务
  7. 完整的清单配置文件和MainActivity代码

优点:系统唤醒,比较稳定

缺点:时间不能把控

4、 JobScheduler 进程拉活APP

  JobScheduler允许在特定状态与特定时间间隔周期执行任务。可以利用它的这个特点完成保活的功能,效果即开启一个定时器,与普通定时器不同的是其调度由系统完成。
  同样在某些ROM可能并不能达到需要的效果


5、双进程守护

双进程守护的思想就是,两个进程共同运行,如果有其中一个进程被杀,那么另一个进程就会将被杀的进程重新拉起,相互保护,在一定的意义上,维持进程的不断运行。
  双进程守护的两个进程,一个进程用于我们所需的后台操作,且叫它本地进程,另一个进程只负责监听着本地进程的状态,在本地进程被杀的时候拉起,于此同时本地进程也在监听着这个进程,准备在它被杀时拉起,我们将这个进程称为 远端进程。
  由于在 Android 中,两个进程之间无法直接交互,所以我们这里还要用到 AIDL (Android interface definition Language ),进行两个进程间的交互。

操作步骤

  1. 新建AIDL文件(可配置方法)
  2. 新建本地service和远端service
  3. 绑定并监听onServiceDisconnected方法,拉起另一进程 

四、总结

  没有一种方式是能够保证你的应用一直存活在内存中的,但是能延长时间也很不错了。

  系统会优先杀死占用内存多的应用,所以想让自己的应用活的更久,还可以从性能上去优化,让其尽可能少的占用内存。