057 组件化的Android

TODO:快速介绍 时间Android组件的主要支撑。

在未知森林里的有知涯上的一棵大树下,兔子在和松鼠小弟对话:

兔子有板有眼的说:

Android中一切都是组件, 程序是由组件组成,比如四大组件:Activity Service BroadcastReceiver ContentProvider 。

松鼠:

是这样啊, 那么俺有几个问题,关于组件:

  1. 谁来负责组件的启动和关闭?
  2. 谁来维护组件的状态?
  3. 谁来管理组件运行时所需要的进程?
  4. 组件之间如何进行通信?

兔子说: “这个问题问的好。Android系统中,构建了有以下的几个模块来支持解决这个问题:

  1. ActivityManager Service
  2. Binder
  3. LowMemory Killer

松鼠说: “这三个呀,他们分别是有什么功能呢?”

兔子说: “这个我略知一二,我试着来为君解析之!”

•ActivityManager Service

简称AMS,负责启动组件,关闭组件,维护组件的状态,运行环境进程的管理等。

  1. 启动组件:
    组件启动时,检查环境,即其所要运行在的进程是否已创建。如果已经创建,就直接通知它加载组件。否则,先将该进程创建起来,再通知它加载组件。
  2. 关闭组件:
    组件关闭时,其所运行在的进程无需关闭,这样就可以让组件重新打开时得到快速启动。
  3. 维护组件状态:
    维护组件在运行过程的状态,这样组件就可以在其所运行在的进程被回收的情况下仍然继续生存。
  4. 进程管理
    在适当的时候主动回收空进程和后台进程,以及通知进程自己进行内存回收

说明:

  1. 组件的UID和Process Name唯一决定了其所要运行在的进程。
  2. 每次组件onStop时,都会将自己的状态传递给AMS维护。
  3. AMS在以下四种情况下会调用trimApplications来主动回收进程:
    A. activityStopped
    B. setProcessLimit
    C. unregisterReceiver
    D. finishReceiver
  4. WMS也会主动回收进程:

WindowManagerService在处理窗口的过程中发生OutOf Memroy时,会调reclaimSomeSurfaceMemoryLocked来回收某些Surface占用的内存,reclaimSomeSurfaceMemoryLocked的逻辑如下所示:

(1).首先检查有没有泄漏的Surface,即那些Session已经不存在但是还没有销毁的Surface,以及那些宿主Activity已经不可见但是还没有销毁的Surface。如果存在的话,就将它们销毁即可,不用KillPids。

(2).如果不存在没有泄漏的Surface,那么那些存在Surface的进程都有可能被杀掉,这是通过KillPids来实现的。

KillPids:

(1). 找中候选进程的最大oom_adj值。

(2). 如果找到的最大oom_adj值恰好位于[ProcessList.HIDDEN_APP_MIN_ADJ(9),ProcessList.HIDDEN_APP_MAX_ADJ(15)]之间,那么就将最大oom_adj值修改为ProcessList.HIDDEN_APP_MIN_ADJ,表示要将所有后台进程都杀掉。

(3). 如果此时杀进程是不安全的,并且找到的最大oom_adj值比ProcessList.SERVICE_ADJ还要小,那么就将将最大oom_adj值设置为ProcessList.SERVICE_ADJ,避免重要进程被杀掉。

(4). oom_adj值大于等于前面找到的最大oom_adj值的候选进程都将被杀掉。

trimApplications:

(1). 杀掉Package已经被Remove了的进程,属于无用进程

(2). 调用updateOomAdjLocked更新所有进程的oom_adj

updateOomAdjLocked-- all:

(1). 根据进程运行状态来更新进程的oom_adj。更新顺序是从最近使用到最近不使用的。如果一个进程是后台进程,那么按照这个顺序进行更新,就意味着最近越是不使用的后台进程,它获得的oom_adj值就越大。后台进程(以及空进程)的oom_adj取值范围[ProcessList.HIDDEN_APP_MIN_ADJ(9),ProcessList.HIDDEN_APP_MAX_ADJ(15)]

(2),如果空进程超过限制,那么最近越是不使用的空进程,就越会被杀掉。

(3). 如果后台进程超过限制,那么最近越是不使用的后台进程,就越会被杀掉。

(4). 通知进程ScheduleTrimMemory。

updateOomAdjLocked-- single:

(1). 调用computeOomAdjLocked计算oom_adj。

(2). 计算oom_adj之后,如果ShchedGroup发生改变,并且变成了THREAD_GROUP_BG_NONINTERACTIVE调度组,那么进程就会被杀掉。

computeOomAdjLocked:

(1). ProcessList.FOREGROUND_APP_ADJ(0):前台进程、有InstrumentionClass的进程、正在接收广播的进程、正在执行ServiceCallback的进程、正在运行有外部依赖的ContentProvider的进程

(2). ProcessList.VISIBLE_APP_ADJ(1):有Activity是Visible的进程

(3). ProcessList.PERCEPTIBLE_APP_ADJ(2):有Activity是Pausing、Paused或者Stopping状态的进程、有Service被设置为Foreground的进程、被设置为Foreground的进程。

(4). ProcessList.HEAVY_WEIGHT_APP_ADJ(3):被设置为重量级App的进程。

(5). ProcessList.BACKUP_ADJ(4):正在执行备份任务的进程。

(6). ProcessList.SERVICE_ADJ(5):最近有活动的Service的进程。

(7). ProcessList.HOME_APP_ADJ(6):HomeApp进程。

(8). ProcessList.PREVIOUS_APP_ADJ(7):前一个显示UI的进程。

(9). ProcessList.SERVICE_B_ADJ(8):oom_adj值等于ProcessList.SERVICE_ADJ的进程超过限制时,最近越是不使用的进程的oom_adj值就会由ProcessList.SERVICE_ADJ变成ProcessList.SERVICE_B_ADJ。

PS:

(1). 如果一个进程运行有绑定至另外一个进程(Client)的ContentProvider或者Service,并且client进程的oom_adj值比该进程的oom_adj小,那么该进程的oom_adj值就会被设置为client进程的oom_adj值,但是不能超过ProcessList.FOREGROUND_APP_ADJ。

(2). ProcessList.PERSISTENT_PROC_ADJ(-12):被设置为persistent的进程,如PhoneApp,不参与oom_adj更新计算。

(3). ProcessList.SYSTEM_ADJ(-16):System进程,不参与oom_adj更新计算。

•Binder

为组件间通信提供支持。 可用于进程间和进程内

是十分高效的IPC机制

  1. 进程间的组件通信时,通信数据只需一次拷贝
  2. 进程内的组件通信时,跳过IPC进行直接的通信

•LowMemory Killer

–内存紧张时回收进程

•由于组件与进程是剥离的,因此进程回收不会影响组件的生命周期

–从低优先级进程开始回收

•EmptyProcess

•HiddenProcess

•PerceptibleProcess

•VisibleProcess

•ForegroundProcess

1.每一个APP进程都有一个oom_adj值,该值是根据进程所运行的组件计算出来的,值越小,优先级就越级。

2.Init和System Server进程的oom_adj等于-16,是最高的,保证不会被杀死。

3.PhoneApp具有persist属性,它的oom_adj被设置为-12,也能保证不会被杀死。

4.可以通过/proc/<pid>oom_adj文件查看进程的oom_adj值。

5.在Linux内核中,子进程的oom_adj值等于父进程的oom_adj,也就是说,Android里面的Native进程的oom_adj值与fork它的进程的oom_adj值一样。

命令行查看工具 dumpsys activity

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容