Android进程管理:Framework层概念

上一篇文章从Native角度讲解了Android进程管理的相关概念,本文将继续从上层的Framework中的进程启动、销毁场景和优先级处理、以及它们与四大组件的种种关联,来逐步解析Android进程管理的其他关键要素 。
进程的启动Android Framework层是运行在ART虚拟机之上的,对于一般的JAVA进程是不具备主动创建进程的能力的 。我们都知道Android中存在四大组件:Activity、Service、BroadcastReceiver和ContentProvider,那么为什么这样划分呢,一个主要的原因是在四大组件的启动阶段,如果宿主进程没有正在运行,那么系统服务进程system_server将会先拉起进程,然后才会继续启动组件 。简而言之,正因为AMS将安卓中进程的创建、销毁及优先级进行了封装,应用侧开发者才能够在对进程无感知的情况的同时使用四大组件 。

Android进程管理:Framework层概念

文章插图
 
启动四大组件方法 startActivity, sendBroadcast, startService/bindService 和 getContentProviderImpl 之所以能够启动进程,是因为它们都会通过发送 binder 消息到 AMS 进行处理,当 AMS 发现对应组件没有在 xml 声明的进程启动时,会先拉起该进程,然后再启动对应组件 。
也就是说,四大组件正是App进程的入口 。它们拉起进程的方式都是一致的,基本流程:
  1. Zygote进程启动,初始化虚拟机及基本环境,同时进入一个无限循环,提供创建 java 进程服务
  2. AMS 通过调用 Process.start() 方法,发送 socket 信息到 Zygote 进程
  3. Zygote 进程处理消息,并通过fork创建应用进程
  4. 应用进程反射调用 ActivityThread.main 方法,进入自身逻辑 (初始化 Looper/Binder 等主要服务 )
  5. AMS 创建进程成功后,会将进程以 ProcessRecord 的形式进行封装、管理 。
彩蛋:实用的进程相关adb命令
Java进程的创建与销毁实时
adb logcat -b events | grep proc**07-16 14:19:23.35747744800 I am_proc_start: [0,30314,10063,com.koushikdutta.vysor,activity,com.koushikdutta.vysor/.StartActivity]07-16 14:19:23.37547746027 I am_proc_bound: [0,30314,com.koushikdutta.vysor]07-16 14:19:31.62147745281 I am_proc_died: [0,30314,com.koushikdutta.vysor,900,17]获取应用进程中组件详细信息
adb shell dumpsys activity p <packageName>*APP* UID 10115 ProcessRecord{4114d9d 18987:com.ss.android.ugc.aweme/u0a115}user #0 uid=10115 gids={50115, 20115, 9997, 3002, 3003, 3001}requiredAbi=armeabi-v7a instructionSet=armclass=com.ss.android.ugc.aweme.app.host.HostApplication...// adj, procState优先级信息oom: max=1001 curRaw=0 setRaw=0 cur=0 set=0curSchedGroup=2 setSchedGroup=2 systemNoUi=false trimMemoryLevel=0curProcState=2 repProcState=2 pssProcState=5 setProcState=2...**Activities**:- ActivityRecord{5e38d19 u0 com.ss.android.ugc.aweme/.main.MainActivity t948}**Services**:- ServiceRecord{13f23bc u0 com.ss.android.ugc.aweme/com.tt.miniapphost.process.base.HostCrossProcessCallService}...**Connections**:- ConnectionRecord{77ae579 u0 CR com.ss.android.ugc.aweme/com.ss.android.socialbase.downloader.downloader.IndependentProcessDownloadService:@30b4240}...**Published Providers**:- com.umeng.message.provider.MessageProvider-> ContentProviderRecord{76d000a u0 com.ss.android.ugc.aweme/com.umeng.message.provider.MessageProvider}...**Connected Providers**:- c887614/com.android.providers.settings/.SettingsProvider->18987:com.ss.android.ugc.aweme/u0a115 s1/1 u0/0 +19h23m3s147ms- c4d7fba/com.android.providers.media/.MediaProvider->18987:com.ss.android.ugc.aweme/u0a115 s0/1 u1/2 +1m10s935ms**Receivers**:- ReceiverList{4afbc5 18987 com.ss.android.ugc.aweme/10115/u0 remote:687d23c}...获取应用优先级信息
adb shell dumpsys activity oProc 0: foreT/A/TOPtrm: 0 18987:com.ss.android.ugc.aweme/u0a115 (top-activity)oom: max=1001 curRaw=0 setRaw=0 cur=0 set=0state: cur=TOPset=TOPlastPss=268MB lastSwapPss=0.00 lastCachedPss=0.00cached=false empty=false hasAboveClient=false进程的优先级Android Framework中进程优先级的衡量单位有两种,除了 adj (对应 lmk 的 oom_score_adj)之外,新添了 procState 变量 。这两个优先级相辅相成,adj 更多的用在给 lmk 判断该进程是否应该被杀死,而procState 更多的给 Framework 层的服务给进程状态"定级",例如,AMS可以简单粗暴的通过判断 procState 是否小于等于 PROCESS_STATE_IMPORTANT_FOREGROUND 来判断该进程是否为"前台进程":
[ActivityManagerService.java]
@Overridepublic boolean isAppForeground(int uid) {    synchronized (this) {        UidRecord uidRec = mactiveUids.get(uid);        if (uidRec == null || uidRec.idle) {            return false;        }        return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;    }}


推荐阅读