Android进程管理:Framework层概念( 二 )

这里的 UidRecord 是 Android 常用的权限管理方案,如果没有做修改的话,普通应用创建的进程都是在同一个 uid 里的 。在系统侧,Android 常常通过 uid 来划分对应的进程是否具有相应的优先级 。
关于Android中adj与procState具体值的含义,可以查看文章最后的附录表格,具体场景仅供参考 。如果需要细致判定当前进程优先级的状态,通过源码分析最为直观 。
adj、schedGroup、procState和adjType的核心计算步骤是在AMS中的computeOomAdjLocked方法完成的,如图:

Android进程管理:Framework层概念

文章插图
 
这个方法的核心执行无外乎以下几个功能:
  1. 首先检查该进程是否处于高优场景中,如前台Activity、正在运行RemoteAnimation,正在处理广播和Service等
  2. 该进程是否是某种特殊进程,如Home,height weight和backup
  3. 是否存在进程因为service和content provider互相绑定提升优先级的情况
  4. 如果都不是上述情况,处于的优先级都比较低,最低的是cache进程,AMS对系统整体cache进程个数有阈值限制,超过上限就会触发清理操作
彩蛋:使用framework中的"自相矛盾"进行保活
进程保活无外乎也是一种普通应用对操作系统的攻击手段,对于一般的攻击手段,我把它理解成使用开发者约定俗成的规则漏洞来突破普通用户原有权限的行为 。
比如说 buffer overflow,是利用了旧版本C编译器在切换函数堆栈时,没有有效检查堆栈信息作用范围的漏洞 。使得普通应用用户可以利用超长的栈内信息覆盖调原有的堆栈跳转信息,使得应用执行其它意想不到的程序 。通过这种方式可以获取到root权限;又比如说 TCP 劫持,是利用了发送方与接收方没有很好的 SEQ和ACK 序列的校验手段,使得中间者可以通过控制 SEQ和ACK的数值来控制正常通信方的流程 。
方式一:bindService 互相绑定以提升优先级这种优先级方式分为两种
第一种,依赖高优先级 client:
if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {    switch (procState) {        case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:        case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:            // Something else is keeping it at this level, just leave it.            break;        case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:        case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:        case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:        case ActivityManager.PROCESS_STATE_SERVICE:            procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;            app.adjType = mayBeTopType;            app.adjSource = mayBeTopSource;            app.adjTarget = mayBeTopTarget;            ...    }}maybeTop 为 true 需要 ContentProvider 或者 Service 的 client 正在前台显示 Activity
同理,通过让用户选择该client来提供服务,例如WallPaperService,可以让system_server成为client,以此来提高进程优先级 。
第二种,两个进程互相绑定:
if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {    clientProcState =            ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;} else if (mWakefulness                == PowerManagerInternal.WAKEFULNESS_AWAKE &&        (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)                != 0) {    clientProcState =            ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;} else {    clientProcState =            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;}...if (procState > clientProcState) {    procState = clientProcState;    if (adjType == null) {        adjType = "service";    }}


推荐阅读