Android开发:进程保活

概念:

进程在内存中长存,怎么杀也杀不死。就算杀死了还能活起来。

咱先了解一下:那咱的应用是怎么死的呢

1、被用户主动kill掉

2、被一些安全软件kill掉

关于进程保活

一、Android进程优先级

1、Foreground process 前台进程

当前用户操作的进程,系统内存足够的话不会回收,如果不足则回收。

A. 拥有用户正在交互的 Activity(已调用 onResume())

B. 拥有某个 Service,后者绑定到用户正在交互的 Activity

C. 拥有正在“前台”运行的 Service(服务已调用 startForeground())

D. 拥有正执行一个生命周期回调的 Service(onCreate()、onStart() 或 onDestroy())

E. 拥有正执行其 onReceive() 方法的 BroadcastReceiver
 

2、Visible process 可见进程

没有任何前台组建,但会影响页面展示。系统内存足够的话不会回收,如果不足则回收。

A. 拥有不在前台、但仍对用户可见的 Activity(已调用 onPause())。

B. 拥有绑定到可见(或前台)Activity 的 Service

3、Service process 服务进程

通常会执行一些用户操作,如播放音乐。除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

4、Background process 后台进程。

后台进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。 通常会有很多后台进程在运行,因此它们会保存在 LRU 列表中,以确保包含用户最近查看的 Activity 的进程最后一个被终止。如果某个 Activity 正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该 Activity 时,Activity 会恢复其所有可见状态。

A. 对用户不可见的 Activity 的进程(已调用 Activity的onStop() 方法)

5、Empty process 空进程。

保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。 为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程。

A. 不含任何活动应用组件的进程

  具体地,活动进程指的就是用户正在操作的程序,是前台进程,可以看到且能够操作;可见进程就是看得见摸不着的,不能直接操作的进程;服务进程是没有界面的一直在后台工作的进程,优先级不高,当系统内存不足时会被杀死,再次充裕的时候会再次开启;后台进程就是用户按了"back"或者"home"后,程序本身看不到了,但是其实还在运行的程序,比如Activity调用了onPause方法系统可能随时终止它们,回收内存.空进程:某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个被处理!

二、Android进程回收策略

进程是怎么被杀的呢?系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。打开的应用越多,后台缓存的进程也越多。在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。那这个不足怎么来规定呢,那就是内存阈值,我们可以使用cat /sys/module/lowmemorykiller/parameters/minfree来查看某个手机的内存阈值。

注意这些数字的单位是page. 1 page = 4 kb.上面的六个数字对应的就是(MB): 72,90,108,126,144,180,这些数字也就是对应的内存阀值,内存阈值在不同的手机上不一样,一旦低于该值,Android便开始按顺序关闭进程. 因此Android开始结束优先级最低的空进程,即当可用内存小于180MB(46080*4/1024)。

  进程是有它的优先级的,这个优先级通过进程的adj值来反映,它是linux内核分配给每个系统进程的一个值,代表进程的优先级,进程回收机制就是根据这个优先级来决定是否进行回收,adj值定义在com.android.server.am.ProcessList类中,这个类路径是${android-sdk-path}\sources\android-23\com\android\server\am\ProcessList.java。oom_adj的值越小,进程的优先级越高,普通进程oom_adj值是大于等于0的,而系统进程oom_adj的值是小于0的,我们可以通过cat /proc/进程id/oom_adj可以看到当前进程的adj值。

  也就是说,oom_adj越大,占用物理内存越多会被最先kill掉

三、Android进程保护方案

1、利用系统广播拉活。

缺陷:

A 广播接收器被管理软件、系统软件通过“自启管理”等功能禁用的场景无法接收到广播,从而无法自启。

B 系统广播事件不可控,只能保证发生事件时拉活进程,但无法保证进程挂掉后立即拉活。

2、利用系统Service机制拉活。

缺陷:

A Service 第一次被异常杀死后会在5秒内重启,第二次被杀死会在10秒内重启,第三次会在20秒内重启,一旦在短时间内 Service 被杀死达到5次,则系统不再拉起。

B 进程被取得 Root 权限的管理工具或系统工具通过 forestop 停止掉,无法重启。

3、利用Native进程拉活。

主要思想:利用 Linux 中的 fork 机制创建 Native 进程,在 Native 进程中监控主进程的存活,当主进程挂掉后,在 Native 进程中立即对主进程进行拉活。

主要原理:在 Android 中所有进程和系统组件的生命周期受 ActivityManagerService 的统一管理。而且,通过 Linux 的 fork 机制创建的进程为纯 Linux 进程,其生命周期不受 Android 的管理。

Android5.0后不允许拉活

4、JobScheduler机制拉活。

该方案主要适用于 Android5.0 以上版本手机。

该方案在 Android5.0 以上版本中不受 forcestop 影响,被强制停止的应用依然可以被拉活,在 Android5.0 以上版本拉活效果非常好。

5、账号同步机制拉活。

猜你喜欢

转载自blog.csdn.net/s297165331/article/details/88949403