Android 进程相关

Android 进程

进程的创建

在Android系统中,进程可以分为系统进程应用进程两大类

  • 系统进程

    系统内置的(例如:initzygotesystem_server)进程,这一部分是操作系统中必不可少的一部分。这部分进程的数量通常是固定的(出厂或者系统升级之后就确定了),并且这部分进程通常是一直存活,常驻内存的。系统进程的异常或者退出可能会导致设备无法正常使用

    这一部分进程的作用在于

    • 管理硬件设备
    • 提供访问设备的基本能力
    • 管理应用进程
  • 应用进程

    是指程序运行的进程,这些程序可能是系统出厂自带的(短信、电话等),也有可能是用户自己安装的(淘宝、支付宝等)。这部分进程在每个人使用的设备上通常是不一样的。如何管理着一些不确定的应用进程,就是操作系统本身要仔细考虑的内容,也是衡量一个操作系统好坏的重要指标

init进程

​ 在Android系统中,所有进程号都是不确定的,只有init进程例外(进程号为固定的1),因为这个进程一定是系统跑起来的第一个进程,它掌握着整个系统的启动逻辑。

​ 因为Android可能运行在各种不通的平台、不同的设备上,所以,启动逻辑也是各有千秋。为了应对各平台的和设备的需求,init进程的初始化工作通过init.rc(这个通过Android Init Language语法来进行配置)这个配置文件来管理。这部分配置并不是只有一个文件,只是因为配置文件的主入口文件是init.rc,这个主入口文件会通过import来引入其他的几个文件,所以暂时统称这些文件为init.rc

​ 在init.rc中需要配置系统启东时该做哪些事情,以及应该启动那些系统进程。这其中有两个特别重要的进

  1. zygote

    这个翻译过来就是“受精卵”。所有的进程都是由zygotefork出来的子进程,因此zygote是所有应用程序的父进程

    init.rc会根据平台不一样,选择下面的几个文件中的一个来启动zygote进程,这几个文件的大致内容都是一样的

    • init.zygote32.rc
    • init.zygote32_64.rc
    • init.zygote64.rc
    • init.zygote64_32.rc

    以init.zygote32.rc文件为例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    > service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    > class main
    > socket zygote stream 660 root system
    > onrestart write /sys/android_power/request_state wake
    > onrestart write /sys/power/state on
    > onrestart restart audioserver
    > onrestart restart cameraserver
    > onrestart restart media
    > onrestart restart netd
    > writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
    >

    这段配置中,启动了一个名为zygote的服务进程,这个进程是通过/system/bin/app_process这个可执行程序创建的,并且在启动它的时候传递了-Xzygote /system/bin --zygote --start-system-server class main这些参数。在这个进程启动以后,会启动一个socket套接字,并通过Looper一直在这个套接字上等待连接,所有应用进程都是通过发送数据到这个套接字上,然后有zygote创建的

    app_process的源码在frameworks/base/cmds/app_process/app_main.cpp

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    //以下仅为部分代码
    246 while (i < argc) {
    247 const char* arg = argv[i++];
    248 if (strcmp(arg, "--zygote") == 0) {
    249 zygote = true;
    250 niceName = ZYGOTE_NICE_NAME;
    251 } else if (strcmp(arg, "--start-system-server") == 0) {
    252 startSystemServer = true;
    253 } else if (strcmp(arg, "--application") == 0) {
    254 application = true;
    255 } else if (strncmp(arg, "--nice-name=", 12) == 0) {
    256 niceName.setTo(arg + 12);
    257 } else if (strncmp(arg, "--", 2) != 0) {
    258 className.setTo(arg);
    259 break;
    260 } else {
    261 --i;
    262 break;
    263 }
    264 }


    279 if (startSystemServer) {
    280 args.add(String8("start-system-server"));
    281 }
    282


    306 if (zygote) {
    307 runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    308 } else if (className) {
    309 runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    310 } else {
    311 fprintf(stderr, "Error: no class name or --zygote supplied.\n");
    312 app_usage();
    313 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    314 return 10;
    315 }

    在这里会进行一次判断,根据参数不同,执行不同的操作

    这其中的runtime.start就是启动Java的虚拟机,并在虚拟机中启动指定的类,然后接下来的逻辑就在ZygoteInit.java中了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    693 try {
    694 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
    695 RuntimeInit.enableDdms();
    696 // Start profiling the zygote initialization.
    697 SamplingProfilerIntegration.start();
    698
    699 boolean startSystemServer = false;
    700 String socketName = "zygote";
    701 String abiList = null;
    702 for (int i = 1; i < argv.length; i++) {
    703 if ("start-system-server".equals(argv[i])) {
    704 startSystemServer = true;
    705 } else if (argv[i].startsWith(ABI_LIST_ARG))
    ......
    }



    742 Zygote.nativeUnmountStorageOnInit();
    743
    744 ZygoteHooks.stopZygoteNoThreadCreation();
    745
    746 if (startSystemServer) {
    747 startSystemServer(abiList, socketName);
    748 }
    749
    750 Log.i(TAG, "Accepting command socket connections");
    751 runSelectLoop(abiList);
    752
    753 closeServerSocket();
    754 } catch (MethodAndArgsCaller caller) {
    755 caller.run();
    756 } catch (RuntimeException ex) {
    757 Log.e(TAG, "Zygote died with exception", ex);
    758 closeServerSocket();
    759 throw ex;
    760 }
    761 }

    精髓所在:

    1. 通过registerZygoteSocket(socketName)注册Zygote Socket

    2. 通过preload()预先加载所有应用都需要的公共资源(如:Framwork相关的一些基础类和Resource资源)(ps:开发者通过Android SDK开发应用所调用的API实现都在Framework中)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      191    static void preload() {
      192 Log.d(TAG, "begin preload");
      193 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "BeginIcuCachePinning");
      194 beginIcuCachePinning();
      195 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      196 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses");
      197 preloadClasses();
      198 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      199 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources");
      200 preloadResources();
      201 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      202 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
      203 preloadOpenGL();
      204 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
      205 preloadSharedLibraries();
      206 preloadTextResources();
      207 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
      208 // for memory sharing purposes.
      209 WebViewFactory.prepareWebViewInZygote();
      210 endIcuCachePinning();
      211 warmUpJcaProviders();
      212 Log.d(TAG, "end preload");
      213 }

      好处是:

      • 加快应用启动速度,因为这些资源在zygote进程启动的时候已经加载好了
      • 通过共享的方式节省内存,这是Linux本身提供的机制,父进程已经加载的内容可以在子进程中进行共享,而不用多份数据拷贝,如果子进程对这些数据进行了修改,那另当别论
    3. 通过startSystemServer(abList, socketName)启动system_server

    4. 通过runSelectLoop(abList),在Looper上等待连接

  2. system_server

这是一个系统服务进程,zygote进程启动以后会根据需要启动system_server进程。Framwork层的几乎所有服务都位于这个进程中,这其中就包括了Android四大组件中的Service

system_server中包含了大量的系统服务

  • 负责网络管理的NeteworkManagementService
  • 负责窗口管理的WindowManagerService
  • 负责震动管理的VibratorService
  • 负责输入管理的InputManagerService

下面2重点讲一下**ActivityManagerService**

上面我提到过,zygote进程在启动后会启动一个socket,然后一直咋这个socket等待连接。会连接它的就是ActivityManagerService,因为ActivityManagerService掌握了所有应用程序的创建。

所有应用程序的进程都是由ActivitymanagerService通过socket发送创建请求给zygote进程,然后由zygote fork创建的。

ActivityManagerService通过Process.start方法来请求zygote创建进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

502 public static final ProcessStartResult start(final String processClass,
503 final String niceName,
504 int uid, int gid, int[] gids,
505 int debugFlags, int mountExternal,
506 int targetSdkVersion,
507 String seInfo,
508 String abi,
509 String instructionSet,
510 String appDataDir,
511 String[] zygoteArgs) {
512 try {
513 return startViaZygote(processClass, niceName, uid, gid, gids,
514 debugFlags, mountExternal, targetSdkVersion, seInfo,
515 abi, instructionSet, appDataDir, zygoteArgs);
516 } catch (ZygoteStartFailedEx ex) {
517 Log.e(LOG_TAG,
518 "Starting VM process through Zygote failed");
519 throw new RuntimeException(
520 "Starting VM process through Zygote failed", ex);
521 }
522 }

这个函数会将启动进程所需要的参数组装好,并通过socket发送给zygote进程,然后zygote进程根据发送过来的参数将进程fork出来

1
2
3
4
5
6
7
8
3487  private final void startProcessLocked(ProcessRecord app, String hostingType,
3617 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
......
Process.ProcessStartResult startResult = Process.start(entryPoint,
3744 app.processName, uid, uid, gids, debugFlags, mountExternal,
3745 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3746 app.info.dataDir, entryPointArgs);
}

ActivityManagerService中,调用Process.stat的地方是下面这个地方(其实四大组件进程的创建,都是调用这里的startProcessLocked这个方法而创建的)

对于每一个应用进程,在ActivityManagerService中,都有一个ProcessRecord与之对应,这个对象记录记录了应用程序的所有详细状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* ProcessRecord所存在的集合
*/

//一、按名称和uid组织的集合
/**
* All of the applications we currently have running organized by name.
* The keys are strings of the application package name (as
* returned by the package manager), and the keys are ApplicationRecord
* objects.
*/
final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();


//二、按pid组织的集合
/**
* All of the processes we currently have running organized by pid.
* The keys are the pid running the application.
*
* <p>NOTE: This object is protected by its own lock, NOT the global
* activity manager lock!
*/
final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();

​ 以上,总结就是

关于应用组件

因为,当某个应用组件启动且该应用没有运行其他任何组件时,Android系统会使用单个执行行线程为应用启动新的Linux进程,所以四大组件中的任何一个开始都会导致应用进程的创建。

在应用程序中,我们可以通过以下方法启动相应的东西

  • startActivity(Intent intent)启动Activity
  • startService(Intent service) 启动service
  • sendBroadcast(Intent intent) 发送广播
  • ContentResolver中的接口来使用ContentProvider

实际上,这里提到的这些方法,最终都是通过Binder调用到ActivityManagerService中,由其进行处理的。(ps:应用进程和ActivityManagerService所在进程,即system_server进程,是相互独立的)

在Android中,专门提供了Binder框架来提供进程间通讯和方法调用的能力

Activity与进程创建

前面提到过,在ActivityManagerService中,对每一个运行中的Activity都有一个ActivityRecord对象与之对应,这个对象记录了Activity的详细状态

ActivityManagerService中的startActivity()方法接受Context.startActivity的请求

1
2
3
4
5
6
7
8
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

一些零碎的东西

  • ActivityManagerService中通过Stack和Task来管理Activity

  • 每个Activity都属于一个Task,一个Task可能包含多个Activity。一个Stack包含多个Task

  • ActivityStackSupervisor类负责管理所有的Stack

  • Activity的启动过程会牵涉到

    • Intent的解析
    • Stack、Task的查询或者解析
    • Activity进程的创建
    • Activity窗口的创建
    • Activity生命周期的调度

进程的优先级

在Android系统中,进程的优先级影响着以下三个因素

  • 当内存紧张时,系统对于进程的回收策略
  • 系统对于进程的CPU调度策略
  • 虚拟机对于进程的内存分配和垃圾回收策略

具体的,系统对于进程的优先级有如下五个分类

  1. 前台进程
  2. 可见进程
  3. 服务进程
  4. 后台进程
  5. 空进程

优先级的依据

组件与进程的相关信息

  • 每一个Android的应用进程中,都可能包含四大组件中的至少一种

  • 对于运行中的Service和ContentProvider来说,可能有若干个客户端进程正在对其使用

  • 应用进程是由ActivityManagerService发送请求让zygote创建的,并且ActivityManagerService中对于每一个运行中的进程都有一个ProcessRecord对象与之对应

    ProcessRecord简化图

    ProcessRecord记录了组件的相关信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    158 // all activities running in the process
    159 final ArrayList<ActivityRecord> activities = new ArrayList<>();
    160 // all ServiceRecord running in this process
    161 final ArraySet<ServiceRecord> services = new ArraySet<>();
    162 // services that are currently executing code (need to remain foreground).
    163 final ArraySet<ServiceRecord> executingServices = new ArraySet<>();
    164 // All ConnectionRecord this process holds
    165 final ArraySet<ConnectionRecord> connections = new ArraySet<>();
    166 // all IIntentReceivers that are registered from this process.
    167 final ArraySet<ReceiverList> receivers = new ArraySet<>();
    168 // class (String) -> ContentProviderRecord
    169 final ArrayMap<String, ContentProviderRecord> pubProviders = new ArrayMap<>();
    170 // All ContentProviderRecord process is using
    171 final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>();
  • activitys:记录的运行中的Activity

  • services:在程序里面跑这着的

  • executingServices:当前正在执行的服务(需要保持前台

  • connections:记录了对于Service的连接

  • receives:记录了程序中运行的BroadcastProvider

  • pubProviders:运行的ContentProvider

  • conProviders:记录了对于ContentProvider的连接

    连接就是对于客户端使用状态的记录,对于Service和ContentProvider是类似的,每有一个客户端就要记录一个连接。连接的意义在于:连接的客户端的进程优先级会影响被使用Service和ContentProvider所在进程的优先级。

    所有的这些组件的状态就是其所在的进程优先级的决定性因素,组件状态指:

  • Activity是否在前台,用户是否可见

  • Service正在被哪些客户端使用

  • ContentProvider正在被哪些客户端使用

  • Service正在被哪些客户端使用

  • BroadcastReceiver是否正在接受广播

优先级的基础

oom_score_adj

对于每一个运行中的进程,Linux内核都通过proc文件系统暴露这样一个文件来允许其他程序修改指定进程的优先级:/proc/[pid]/oom_score_adj (pid是 Linux 中在其命名空间中唯一标识进程而分配给它的一个号码,称做进程ID号,简称PID。在使用 fork 或 clone 系统调用时产生的进程均会由内核分配一个新的唯一的PID值)

这个文件允许的值的范围是-1000~+1000之间,值越小,进程越重要。当内存紧张时,系统就是遍历进程,根据这个值来确定杀死哪些进程以回收内存

ProcessRecord中,下面这属性反映了oom_score_adj的值

1
2
3
4
5
92    int maxAdj;                 // Maximum OOM adjustment for this process
93 int curRawAdj; // Current OOM unlimited adjustment for this process
94 int setRawAdj; // Last set OOM unlimited adjustment for this process
95 int curAdj; // Current OOM adjustment for this process
96 int setAdj; // Last set OOM adjustment for this process

maxAdj制定了该进程允许oom_score_adj最大值,这个属性主要是给系统应用和常驻内存的进程使用,这些进程的优先级的计算方法与应用进程的计算方法不一样,通过设置maxAdj保证这些应用一直拥有较高的优先级

curAdj开头的这一组,记录的一次优先级计算的结果,在计算完成以后,会将curAdj赋值给setAdj.

××RawAdj记录了没有经过限定(指其中的值可能超过了oom_score_adj文件所规定的-1000~~1000)的adj值

为了便于管理,在ProcessList中,预定义了oom_score_adj的可能取值,其实这种预定义也是对应用进程的一种分类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
58  static final int UNKNOWN_ADJ = 1001; 
59
60 // This is a process only hosting activities that are not visible,
61 // so it can be killed without any disruption.
62 static final int CACHED_APP_MAX_ADJ = 906;
63 static final int CACHED_APP_MIN_ADJ = 900;
64
65 // The B list
61 // so it can be killed without any disruption.
62 static final int CACHED_APP_MAX_ADJ = 906;
63 static final int CACHED_APP_MIN_ADJ = 900;
64
65 // The B list of SERVICE_ADJ -- these are the old and decrepit
66 // services that aren't as shiny and intereof SERVICE_ADJ -- these are the old and decrepit
66 // services that aren't as shiny and interesting as the ones in the A list.
67 static final int SERVICE_B_ADJ = 800;
68
69 // This is the process of the previous application that the user was in.
70 // This process is kept above other things, because it is very common to
71 // switch back to the previous app. This is important both for recent
72 // task switch (toggling between the two top recent apps) as well as normal
73 // UI flow such as clicking on a URI in the e-mail app to view in the browser,
74 // and then pressing back to return to e-mail.
75 static final int PREVIOUS_APP_ADJ = 700;
76
77 // This is a process holding the home application -- we want to try
78 // avoiding killing it, even if it would normally be in the background,
79 // because the user interacts with it so much.
80 static final int HOME_APP_ADJ = 600;
81
82 // This is a process holding an application service -- killing it will not
83 // have much of an impact as far as the user is concerned.
84 static final int SERVICE_ADJ = 500;
85
86 // This is a process with a heavy-weight application. It is in the
87 // background, but we want to try to avoid killing it. Value set in
88 // system/rootdir/init.rc on startup.
89 static final int HEAVY_WEIGHT_APP_ADJ = 400;
90
91 // This is a process currently hosting a backup operation. Killing it
92 // is not entirely fatal but is generally a bad idea.
93 static final int BACKUP_APP_ADJ = 300;
94
95 // This is a process only hosting components that are perceptible to the
96 // user, and we really want to avoid killing them, but they are not
97 // immediately visible. An example is background music playback.
98 static final int PERCEPTIBLE_APP_ADJ = 200;
99
100 // This is a process only hosting activities that are visible to the
101 // user, so we'd prefer they don't disappear.
102 static final int VISIBLE_APP_ADJ = 100;
103 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
104
105 // This is the process running the current foreground app. We'd really
106 // rather not kill it!
107 static final int FOREGROUND_APP_ADJ = 0;
108
109 // This is a process that the system or a persistent process has bound to,
110 // and indicated it is important.
111 static final int PERSISTENT_SERVICE_ADJ = -700;
112
113 // This is a system persistent process, such as telephony. Definitely
114 // don't want to kill it, but doing so is not completely fatal.
115 static final int PERSISTENT_PROC_ADJ = -800;
116
117 // The system process runs at the default adjustment.
118 static final int SYSTEM_ADJ = -900;
119
120 // Special code for native processes that are not being managed by the system (so
121 // don't have an oom adj assigned by the system).
122 static final int NATIVE_ADJ = -1000;

FOREGROUND_APP_ADJ = 0,这个是前台应用进程的优先级,是用户正在进行交互的应用,他们很重要,系统不应当回收。这也是普通应用能够获取到的最高优先级

VISIBLE_APP_ADJ是具有可见Activity进程的优先级:同一时刻,不一定只有一个Activity是可见的,如果前台Activity设置了透明属性,那么背后的Activity也是可见的

PERCEPTIBLE_APP_ADJ是指用户可感知的进程

  • 进程中包含了处于Pause状态的或者正在pause的activity
  • 进程中包含了正在stop的activity
  • 进程中包含了前台的Service

PREVIOUS_APP_ADJ描述的是前一个应用的优先级。所谓“前一个应用”是指:在启动新的Activity时,如果新启动的Activity是属于一个新的进程的,那么当前即将被stop的Activity所在的进程便会成为“前一个应用”进程

HEAVY_WEIGHT_APP_ADJ 描述的重量级进程是指那些通过Manifest指明不能保存状态的应用进程

除了这些常见的应用以外,还有很多常驻内存的系统应用,他们是系统实现的一部分,例如状态栏、keyguard。所以这部分的优先级比所有的应用进程的优先等级更高。PERSISTENT_SERVICE_ADJ = -700PERSISTENT_PROC_ADJ = -800

然后就还有一些核心系统服务,如果这些系统服务不存在,那么系统就将无法工作,所这些应用的优先级最高,几乎任何时候都需要存在的:SYSTEM_ADJ = -900NATIVE_ADJ = -1000

Schedule Group

内核负责了进程的CPU调度,所有运行中的进程并非能平等的获取相等的时间片。在ProcessRecord中,通过Schedule Group来记录进程的调度租

1
2
98    int curSchedGroup;          // Currently desired scheduling class
99 int setSchedGroup; // Last set to background scheduling class

他们可能取值定义在ProcessList.java中

1
2
3
4
5
6
127    // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
128 static final int SCHED_GROUP_BACKGROUND = 0;
129 // Activity manager's version of Process.THREAD_GROUP_DEFAULT
130 static final int SCHED_GROUP_DEFAULT = 1;
131 // Activity manager's version of Process.THREAD_GROUP_TOP_APP
132 static final int SCHED_GROUP_TOP_APP = 2;

Process State

进程的状态会影响虚拟机对于进程的内存分配和垃圾回收的策略,PrecessRecord中的这几个属性记录了进程的状态

1
2
3
4
101    int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
102 int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
103 int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker
104 int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for

这些属性可能的取值定义在ActivityManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
330    /** @hide Process does not exist. */
331 public static final int PROCESS_STATE_NONEXISTENT = -1;
332
333 /** @hide Process is a persistent system process. */
334 public static final int PROCESS_STATE_PERSISTENT = 0;
335
336 /** @hide Process is a persistent system process and is doing UI. */
337 public static final int PROCESS_STATE_PERSISTENT_UI = 1;
338
339 /** @hide Process is hosting the current top activities. Note that this covers
340 * all activities that are visible to the user. */
341 public static final int PROCESS_STATE_TOP = 2;
342
343 /** @hide Process is hosting a foreground service due to a system binding. */
344 public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3;
345
346 /** @hide Process is hosting a foreground service. */
347 public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
348
349 /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
350 public static final int PROCESS_STATE_TOP_SLEEPING = 5;
351
352 /** @hide Process is important to the user, and something they are aware of. */
353 public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
354
355 /** @hide Process is important to the user, but not something they are aware of. */
356 public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
357
358 /** @hide Process is in the background running a backup/restore operation. */
359 public static final int PROCESS_STATE_BACKUP = 8;
360
361 /** @hide Process is in the background, but it can't restore its state so we want
362 * to try to avoid killing it. */
363 public static final int PROCESS_STATE_HEAVY_WEIGHT = 9;
364
365 /** @hide Process is in the background running a service. Unlike oom_adj, this level
366 * is used for both the normal running in background state and the executing
367 * operations state. */
368 public static final int PROCESS_STATE_SERVICE = 10;
369
370 /** @hide Process is in the background running a receiver. Note that from the
371 * perspective of oom_adj receivers run at a higher foreground level, but for our
372 * prioritization here that is not necessary and putting them below services means
373 * many fewer changes in some process states as they receive broadcasts. */
374 public static final int PROCESS_STATE_RECEIVER = 11;
375
376 /** @hide Process is in the background but hosts the home activity. */
377 public static final int PROCESS_STATE_HOME = 12;
378
379 /** @hide Process is in the background but hosts the last shown activity. */
380 public static final int PROCESS_STATE_LAST_ACTIVITY = 13;
381
382 /** @hide Process is being cached for later use and contains activities. */
383 public static final int PROCESS_STATE_CACHED_ACTIVITY = 14;
384
385 /** @hide Process is being cached for later use and is a client of another cached
386 * process that contains activities. */
387 public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 15;
388
389 /** @hide Process is being cached for later use and is empty. */
390 public static final int PROCESS_STATE_CACHED_EMPTY = 16;
391
392 /** @hide The lowest process state number */
393 public static final int MIN_PROCESS_STATE = PROCESS_STATE_NONEXISTENT;
394
395 /** @hide The highest process state number */
396 public static final int MAX_PROCESS_STATE = PROCESS_STATE_CACHED_EMPTY;

优先级的更新

.系统对处于不同状态的进程设置不同的优先级,但实际上,进程的状态是一直在变化的。并且Activity可能会使用其他的Service或者ContentProvider。当Activity的进程优先级发生变化时,它所使用的Service或者ContentProvider的优先级也会随之发生变化

ActivityManagerService中,有两个方法用来更新进程的优先级

  • final boolean updateOomAdjLocked(ProcessRecord app) :针对单个的进程更新优先级

    在许多情况下需要对指定应用的进程更新优先级

    • 当有一个新的进程开始使用本进程的ContentProvider
    • 当本进程中的一个Service被其他进程bind或者unbind
    • 当本进程中的Service执行完成或者退出了
    • 当本进程中一个BroadcastReceive正在接受广播
    • 当本进程中的BackUpAgent启动或者退出了

  • final void updateOomAdjLocked():针对所有的进程更新优先级

    在某些情况下,系统需要对所有的应用进程的优先级进行更新

    • 当有一个新的进程启动时
    • 当有一个进程退出时
    • 当系统正在清理后台进程时
    • 当有一个进程被标记为前台进程时
    • 当有一个进程进入或者退出cached状态时
    • 当系统锁屏或者解锁时
    • 当有一个Activity启动或者退出时
    • 当系统正在处理一个广播事件时
    • 当前台Actiity发生改变时
    • 当有一个Service启东时