Android 多进程使用场景

类似音乐类、跑步健身类、手机管家类等长时间需要在后台运行的应用。这些应用的特点就是,当用户切到别的应用,或者关掉手机屏幕的时候,应用本身的核心模块还在正常运行,提供服务。如果因为手机内存过低,或者是进程重要性降低,导致应用被杀掉,后台服务停止,对于这些应用来说,就是灭顶之灾。合理利用多进程,将核心后台服务模块和其他UI模块进行分离,保证应用能更稳定的提供服务,从而提升用户体验。

举个例子:

现在要做一款音乐播放器,现在有以下几种方案:

A. 在Activity中直接播放音乐。

B. 启动后台Service,播放音乐。

C. 启动前台Service,播放音乐。

D. 在新的进程中,启动后台Service,播放音乐。

E. 在新的进程中,启动前台Service,播放音乐。

首先我们分析A

在A中,我们的播放器是直接在activity中启动的。首先这么做肯定是不对的,我们需要在后台播放音乐,所以当activity退出后就播不了了,之所以给出这个例子是为了控制变量作对比。

然后我们来看下A的使用场景。

音乐播放器无非是打开app,选歌,播放,退到桌面,切其他应用。我们选取了三个场景,打开、按home切换其他应用、按back退回桌面。让我们看一下A的相对应的oom_adj、oom_score、oom_score_adj的值。(下面三张图依次对应为【打开状态】、【按了Home键被切换状态】、【按了Back键被退出状态】)

上图为打开状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Home键状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Back键状态下oom_adj、oom_score、oom_score_adj的值

当我们应用在前台的时候,无论adj还是score还是score_adj,他们的值都非常的小,基本不会被LMK所杀掉,但是当我们按了Home之后,进程的adj就会急剧增大,变为7,相应的score和score_adj也会增大。在上篇文章中我们得知,adj=7即为被切换的进程,两个进程来回切换,上一个进程就会被设为7。当我们按Back键的时候,adj就会被设为9,也就是缓存进程,优先级比较低,有很大的几率被杀掉。

接着我们分析B

B是直接启动一个后台service并且播放音乐,这个处理看起来比A好了很多,那么实际上,B的各个场景的优先级和A又有什么不同呢?让我们来看下B的对应的打开、切换、退出相应的adj、score、score_adj的值。(下面三张图依次对应为【打开状态】、【按了Home键被切换状态】、【按了Back键被退出状态】)

上图为打开状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Home键状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Back键状态下oom_adj、oom_score、oom_score_adj的值

B的情况其实是与A类似的,三种状态的adj、score_adj的值都是一样的,只有score有一点出入,其实分析源码得知,LMK杀进程的时候,score的左右其实并不大,所以我们暂时忽略它。所以,与A相比,他们的adj和score_adj的值都相同,如果遇到内存不足的情况下,这两个应用谁占得内存更大,谁就会被杀掉。不过鉴于A实在activity中播放音乐,所以B还是比A略好的方案。

这里有朋友肯定要问了,为什么切到后台后,adj的值是7而不是5,后台不是还有service在跑吗?

我们通过查看源码可以找出来,当切换Home的时候,会调用ActivityStack.javafinishCurrentActivityLocked函数,然后调用到了ActivityManagerService.javacomputeOomAdjLocked函数,在这里,对进程的ADJ值进行重新计算。

if (app == mPreviousProcess && app.activities.size() > 0) {

if (adj > ProcessList.PREVIOUS_APP_ADJ) {

adj = ProcessList.PREVIOUS_APP_ADJ;

schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;

app.cached = false;

app.adjType = “previous”;

}

if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {

procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;

}

}

当进程为PreviousProcess情况,则ADJ=7。

具体的计算流程请看这里computeOomAdjLocked计算流程

接下来分析C

C的话是启动一个前台Service来播放音乐。让我们来看一下对应的值。(下面三张图依次对应为【打开状态】、【按了Home键被切换状态】、【按了Back键被退出状态】)

上图为打开状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Home键状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Back键状态下oom_adj、oom_score、oom_score_adj的值

在前台的时候,和AB是一样的,adj都是0,当切到后台,或者back结束时,C对应的adj就是2,也就是可感知进程。adj=2可以说是很高优先级了,非root手机,非系统应用已经没有办法将其杀掉了。具体可参见ActivityManagerServicekillBackgroundProcesses方法以及killPackageProcessesLocked方法。adj<5的应用不会被杀掉。

总的来说,C方案比B优秀,拥有前台Service的C更不容易被系统或者其他应用所杀掉了,进程的优先级一下子提高到了2,相对于B来说更稳定,用户体验更好。不过有一点不足是必须启动一个前台service。不过现在大部分的音乐类软件都会提供一个前台service,也就不是什么缺点了。其实也是有灰色方法可以启动一个不显示通知的前台service,这里就不过多介绍了。

那么还有可改进的余地吗?

答案当然是肯定的。

让我们来看看D ,终于我们的主角,多进程登场了。

D把应用进行了拆分,把用于播放音乐的service放到了新的进程内,让我们看一下对应的值。(下面三张图依次对应为【打开状态】、【按了Home键被切换状态】、【按了Back键被退出状态】)

上图为打开状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Home键状态下oom_adj、oom_score、oom_score_adj的值

上图为按了Back键状态下oom_adj、oom_score、oom_score_adj的值

上面三张图对应的是D应用主进程的ADJ相关值,我们可以看出来,跟A类似,adj都是0,7,9。由于少了service部分,内存使用变少,最后计算出的oom_score_adj也更低了,意味着主进程部分也更不容易被杀死。

下面我们看下拆分出的service的相关值

上图为后台Service的oom_adj、oom_score、oom_score_adj的值

因为是service进程,所以不受打开,关闭,切换所影响,这里就放了一张图。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。

技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;

我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 PDF(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

Java语言与原理;
大厂,小厂。Android面试先看你熟不熟悉Java语言

高级UI与自定义view;
自定义view,Android开发的基本功。

性能调优;
数据结构算法,设计模式。都是这里面的关键基础和重点需要熟练的。

NDK开发;
未来的方向,高薪必会。

前沿技术;
组件化,热升级,热修复,框架设计

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多

当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。

不出半年,你就能看出变化!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

我在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多

当然,想要深入学习并掌握这些能力,并不简单。关于如何学习,做程序员这一行什么工作强度大家都懂,但是不管工作多忙,每周也要雷打不动的抽出 2 小时用来学习。

不出半年,你就能看出变化!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值