一. 定义
- Android系统中,当内存不足时会kill掉一些程序(或进程)来释放内存给需要运行的程序来使用。
- 进程的优先级越高,最后才会被kill掉,反之,最低的优先被kill。
二. Android系统中存在的进程
1.Zygote进程
Zygote,受精卵的意思...在Android系统中,所有的系统服务进程SystemServer以及应用程序进程都是由Zygote进程Fork(孕育)出来的。
2.App主进程
每一个App都是运行在一个独立的进程中,当然这个进程也是由Zygote进程Fork出来的。App的进程的名称就是包名,并由AMS(ActivityManagerService)管理,顺带提一下BroadcastReceiver的发送也是由AMS来完成的。
3.App辅助进程
一个App可以拥有多个进程,具体为在AndroidManifest.xml
文件中为Activity或者Service进行配置android:process=""
。同样,辅助进程也是由Zygote Fork出来并由AMS管理。
4.Native进程
Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。由NDK所Fork出的进程称之为Native进程。Native进程自由度较高可以不受AMS管理。另,NDK也可用来做进程保活。
三. Android系统中进程的优先级
Android系统中进程的优先级定义在com.android.server.am.ProcessList
类中,这个类在SDK中可以找到。
主要有以下优先级定义(oom_adj值):
名称 | 说明 |
---|---|
UNKNOWN_ADJ = 16 | 预留最低级别,缓存用可能设置为这个 |
CACHED_APP_MAX_ADJ = 15 | 持有不可见的Activity的进程,也就是后台进程,系统内存不足会被Kill |
CACHED_APP_MIN_ADJ = 9 | 缓存进程,也就是空进程 |
SERVICE_B_ADJ = 8 | 不活跃的进程 |
PREVIOUS_APP_ADJ = 7 | 切换进程,切换应用程序时保存的之前的进程 |
HOME_APP_ADJ = 6 | 与Home交互的进程 |
SERVICE_ADJ = 5 | 包含Service的进程,一般来说Kill掉对用户影响不太大 |
HEAVY_WEIGHT_APP_ADJ = 4 | 高权重进程,在后台运行但是系统尽量不Kill掉 |
BACKUP_APP_ADJ = 3 | 托管备份的进程,Kill掉是一个bad idea |
PERCEPTIBLE_APP_ADJ = 2 | 可被用户感知的进程,比如音乐播放器 |
VISIBLE_APP_ADJ = 1 | 可见进程,用户可以见到的进程,但不一定都是前台进程,有可能是被覆盖的Activity |
FOREGROUND_APP_ADJ = 0 | 前台进程,运行在前台的App的进程 |
PERSISTENT_SERVICE_ADJ = -11 | 重要进程,系统或重要进程绑定的进程 |
PERSISTENT_PROC_ADJ = -12 | 核心进程,系统持续进程,如电话 |
SYSTEM_ADJ = -16 | 系统进程 |
NATIVE_ADJ = -17 | 不由系统管理的Native相关进程 |
查看进程优先级:
//oom_adj的值就是进程的优先级
//查看oom_adj值
cat /proc/${pid}/oom_adj
四. Android系统中常见进程
优先级从高到低排列:
1. 前台进程(Foreground process)
满足以下几个条件被视为前台进程:
- 进程持有一个正与用户交互的Activity。
- 进程持有一个满足以下条件的Service:
1、与正在交互的Activity绑定;
2、使用startForeground()
启动的前台服务;
3、Service正在执行生命周期函数,onCreate(), onStart(), or onDestroy()
。 - 进程持有一个正在执行
onReceive()
的BroadcastReceiver。
2. 可见进程(Visible process)
- 进程持有一个可见的Activity,比如被Dialog遮挡进入
onPause()
状态的Activity。 - 进程持有一个和可见的(或前台的)Activity绑定的Service。
3 服务进程(Service process)
- 进程持有一个使用
startService()
开启的服务,且不属于以上两种优先级较高的Service,被视为服务进程。比如后台播放音乐,下载文件。
4 后台进程(Background process)
- 进程持有不可见的,调用了
onStop()
但是没有调用onDestroy()
的Activity,被认为是后台进程。这样做的原因是保存一些Activity用于用户选择和跳转。它们会被保存在一个LRU (least recently used)列表中,系统内存不足时可能会Kill掉最早的Activity,可以通过重写onSaveInstanceState()
在被Kill之前来保存数据。
5 空进程
- 进程中不包含活跃的组件,被认为是空进程。保存这种进程的原因是缓存需要。
五. 提高进程优先级
- AndroidManifest.xml中配置
android:persistent="true"
- 在Service中开启线程做耗时操作,会被判断为服务进程。
-
startForeground()
启动前台服务,记得使用stopForeground()
关闭。 - 与NotificationManager交互,让进程变成可感知进程。
- 使用广播,避免成为空进程。
- 使用Native进程做进程保活(只是思路)。
参考资料:
Android平台App进程优先级
Android基础总结——进程优先级及提高优先级的方法(Service尽量不死之法)