对于Android APP的开发者来说,他们可能更关心的是APP的性能优化,这里我们聊一聊Android系统层面的一些优化,不过这里我要强调的是此文章只涉及到Framework层面的优化,不涉及更底层BSP、Kernel层面的优化。
本文主要从Android系统开机速度、内存优化、进程查杀几个方面进行阐述:
一、开机启动速度优化
关于开机启动的优化网上有人总结过经验,可以参考以下链接:
http://www.ithao123.cn/content-10790538.html (貌似已失效)
这篇文章主要从预加载资源精简、异步加载资源以及提升异步线程优先级的角度出发,实际笔者测试确实也有一定的优化效果。
除此之外,还有其他的启动优化方法嘛?答案是肯定的,还可以从开机启动的进程出发,梳理开机启动的进程。主要思路有:限制第三方应用开机启动;整合或者代理开机启动进程;延迟启动。
限制第三方应用开机启动:主要是观察系统启动后会通过某种广播开启进程的应用,然后清楚这些第三方应用是通过哪种广播启动的,然后在AMS的broadcastIntentLocked()方法中对广播接收者进行过滤,目前笔者的系统中加入了这些广播作为开机禁止的(BOOT_COMPLETED、PRE_BOOT_COMPLETED、CONNECTIVITY_CHANGE、MEDIA_MOUNTED、USB_DEVICE_ATTACHED),可能有人会问,那系统应用如果需要监听这些广播进行开机启动怎么办呢?答案就是白名单机制,通过建立白名单将需要启动的APP加入,可以配合服务器动态下发做到可扩展。有经验的读者可能发现了隐藏在背后的问题了,Android 5.0之后的版本对应用程序的启动做了限制,只有开机后手动进入运行一次才能接收广播。所以这里提到的改动主要是针对5.0以下的系统。在4.4中虽然android系统做了一些改进比如监听开机广播的应用必须手动进入运行一次之后才能接收,但是之后每次开机都能接收了,所以限制是比较宽松的。4.4以下的系统更是只要申请权限就有权开机启动了。
整合或者代理开机启动:这方面主要是因为系统中存在一些进程,开机启动后只会做一些简单的条件判断,如果不符合条件就什么也不做,即使这样也会启动这个应用进程。比如一个Camera的应用模块会开机检测设备有没有插入摄像头,如果没有插入就什么也不做。所以对于这种“条件检查再运行”的应用可以考虑将启动条件检查放入到一个常驻系统的服务中进行,委托该常驻服务进行检测,满足条件再启动该进程。
延迟启动:影响开机速度体验的一个关键因素是用户感知进入到桌面的时间,因此优先展示桌面是最重要的。所谓延迟启动就是将开机启动的广播延迟到桌面加载完成之后再进行发放。通过桌面的远程调用告知AMS桌面已经ready,然后AMS再构造BOOT_COMPLETE的广播进行发送。
二、内存优化
内存优化这里主要是基于Android Low Memory Killer机制之上做的一些依赖于通过查杀后台进程进行内存释放的工作。大家可能都知道android系统中,lmk定义了一个进程的优先级(值越小优先级越高)
每一个优先级对应的都有一个触发动作的内存阈值
进程 | oom_adj | oom_score_adj | Minfree | page | 内存(M) |
FOREGROUND_APP | 0 | 0 | 15600 | 3900 | 15.234375 |
VISIBLE_APP | 1 | 58 | 18000 | 4500 | 17.578125 |
PERCEPTIBLE_APP_ADJ | 2 | 117 | 24000 | 6000 | 23.4375 |
BACKUP_APP_ADJ | 3 | 176 | 28000 | 7000 | 27.34375 |
CACHED_APP_MIN_ADJ | 9 | 529 | 40000 | 10000 | 39.0625 |
CACHED_APP_MAX_ADJ | 15 | 882 | 60000 | 15000 | 58.59375 |
要想在framework中为了优先于底层lmk机制进行查杀,我们需要定义一个大于lmk定义的阈值标准,我们不用每一个等级有对应的值,只需要划分4个查杀等级即可。这四个按照优先级从低往高依次是NONE、LOOSE、MEDIUM、STRICT。这几种优先级对应的内存关系如下:
CACHED_APP_MIN_ADJ + 30MB < NONE级别对应的系统剩余内存 (不做处理,依赖底层机制)
PERCEPTIBLE_APP_ADJ + 20MB < LOOSE级别对应的系统剩余内存 < CACHED_APP_MIN_ADJ + 30MB (查杀优先级adj >=9 的后台进程)
FOREGROUND_APP_ADJ + 11MB < MEDIUM级别对应的系统剩余内存 < PERCEPTIBLE_APP_ADJ + 20MB (查杀优先级adj >= 2的后台进程)
STRICT级别对应的系统剩余内存 < FOREGROUND_APP_ADJ + 11MB (查杀优先级adj >= 0的后台进程))
三、进程查杀
除了之上可以基于内存的进程查杀机制之外,还可以按照后台进程的CPU使用率、IO流量等因素进行后台进程查杀。
四、其他
对于内存限制更为严格的硬件设备来说,还可以考虑应用程序切换到后台立马进行查杀;
在进程查杀过程中可能会出现一些误杀的进程,比如一个应用A通过startActivityForResult启动一个新的应用B等待返回结果,这时候A处于后台,可能被杀掉。这种情况下需要进行区分;
还有如果前台应用在使用一个后台进程的Provider,如果把后台进程杀掉,也会导致前台进程crash;
对于Float Window弹窗的应用,处于其后的应用可能会突然被杀掉。这些在进程查杀的时候都要进行区分。