AndroidApp应用性能优化总结
最近大半年的时间里,大部分投在了某国内新能源汽车的某款AndroidApp开发上。
由于该App是该款车上,常用+重点应用。所以车厂对应用性能的要求比较高。
主要包括:
- 应用冷启动达到***ms。
- 应用热(温)启动达到***ms
- 应用内画面切换响应达到**ms
- 应用内动效/动画/车模等交互时,画面不能有延迟感等等。
- 应用不能有内存泄露,内存稳定在**MB
诸如上面的内容,还有一些,就不详细列出来了。
因为之前没有直接做过AndroidApp开发,之前大部分时间在做Framework/System开发。所以对于应用的性能优化,相当于站在系统角度,重新研究了一遍。
经历大半年时间后,曾经作为系统侧不理解应用开发人员的某些东西,突然理解了。也更加觉得,如果在应用开发前能有一个好的整体架构设计,那很多事会半功倍。
这里总结一下,Android应用总结时用到的一些方法。
启动性能优化
冷启动和温启动
Android应用启动,主要指启动App到其显示出第一帧的时间。大类上可以分为冷启动、热启动两种(细分的话,还有一种叫温启动),两种方式主要区别在于 App的进程是否已被加载。
简单理解
冷启动: Android系统Fork进程,加载App资源,然后Activity被启动走Activity的生命周期(onCreate、onStart、onResume)等等。
热启动: AndroidApp的进程已经存在,App资源已经加载完成。在这个前提下,启动App的时间(App画面显示。)
利用Trace加以分析
trace常用来分析启动的优化,可以利用AndroidStudio自带的Profile工具。也可以使用类似如下命令
bash
# 抓取10S Trace,并保存在 /data/misc/perfetto-traces/trace_file.perfetto-trace文件中。
adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 10s sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
Anroid应用执行期间(比如启动,比如画面切换)的动作、每步消耗时间,会被记录到Trace中。然后利用AndroidStudio自带的工具,或者perfetto网站分析Trace。
如下图,通过perfetto网站分析的Trace内容。
分析Trace中主要耗时点,针对主要耗时点一般可以考虑如下优化方向:
- 资源(比如图片)加载时间是否过长?资源是否可以压缩。
- 布局类型是否合理,布局内容中是否可以写死某些内容避免动态计算
- 布局中的资源是否可以用时加载(用于优化启动速度)
- 布局嵌套是否过多?
- 是否可以利用多核特性(比如把操作分散到其他线程中,并行处理)
- 是否存在重复操作?
- 父类中是否存在多余的操作?
- 是否利用了缓存机制,让某些对象(比如View)不会反复重新创建?
- Log日志输出是否合理,是否过于频繁?
如果系统提供的Trace不足,可以在应用代码中加入自定义Trace.
java
Trace.beginSection("TAG")
Trace.endSection();
通过仔细分析Trace,可以对应用性能做很大的提升。
利用Log分析
这里的Log指,应用自身的 Log,以及Android系统的Log。
应用自身的 Log主要包括:
- Activity生命周期的Log
- 与外部交互的Log,比如外部接口是否耗时的分析。
- 加载某些比较大资源的log。
Android系统Log主要包括:
- 性能Log,events分区的log 。通过logcat -b events 输出。性能Log中,会记录Activity每一个阶段的耗时。
- WMS、AMS、IMS的log,抓取windowmanageservice,和ActivitymanagerService的log,InputManagerservice的log,用来帮助分析应用系统。
其他优化手段
在通过Trace和Log分析应用后,对于某些无法直接优化其响应速度的内容,可以考虑
- 提前加载或初始化:放入Application中提前加载,对于热(温)启动方式有效。
- 异步加载:对于异步加载的情况下,有些时候需要使用 占位图。
- 占位图:比如加载某个动效时,动效无法立刻显示。那么使用将动效第一帧做成一个静态图,提前显示。当动效加载完成并显示后,再隐藏占位图。
- 加入动画效果:比如加入淡入、淡出的效果,单纯从视觉上优化。
内存优化
内存优化主要包括
- 应用运行时,内存是否超过标准(过大)
- 应用运行时,内存是否存在泄露情况
内存优化时,可以考虑几个方面
- 缩减App包的大小。因为App本身资源少了,内存自然少。
- 考虑代码中,是否存在不用的对象,是否可以用简单对象(比如不用Hashmap之类)。当然考虑的时候,也要考虑运行速度。
- 利用内存分析工具,分析内存是否泄露。
比如shark-cli,利用该工具可以分析App是否存在内存泄露。
bash
shark-cli -p 包名
上面的命令输出如下结果
bash
.....
====================================
HEAP ANALYSIS RESULT
====================================
3 APPLICATION LEAKS
References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
177 bytes retained by leaking objects
Displaying only 1 leak trace out of 3 with the same signature
....
稳定性优化
稳定性,主要是指App的健壮性。不会异常崩溃,不会闪白或者闪黑。
稳定性,主要靠对应用进行测试,比如测试人员,比如自动化工具等等。
工具的话,monkey是比较常见的工具,可以通过monkey模拟用户的随机操作。关于该用法,网络上有很多说明。
Android应用的性能优化方法,不仅限于本文介绍的这些,还有很多优化的方法。总的来说的话,其实就是让应用,不做多余的事情、使用恰当的资源、提前加载以及充分利用并行。