Android性能测试与优化
本文目录:
一、性能测试
1.内存消耗 2.CPU占用 3.帧率GPU 4.流量消耗 5.电量消耗
二、性能优化
1.卡顿优化 2.耗电优化 3.安装包大小优化 4.内存优化 5.稳定性优化
一、性能测试
1、内存消耗
1.1 使用Android Profiler
1.2 使用adb
输入命令:adb shell dumpsys meminfo PackageName
1.3 使用Lint
Android Studio->Analyze->Inspect Code
1.4 使用MAT
1.5 使用Heap Snapshot
2、CPU占用
2.1 使用Android Profiler
3、帧率GPU
3.1 使用“GPU呈现模式分析”中的“在adb shell dumpsys gfxinfo中”选项。
① 进入Android设备的开发者选项,勾选“GPU呈现模式分析”中的“在adb shell dumpsys gfxinfo中”选项。
② 在电脑的terminal中进入<SDK目录>下的platform-tools文件夹,输入命令adb shell dumpsys gfxinfo 包名,结果如图所示
③ 参数说明
- Graphics info for pid 7821 [com.longsh1z.myapplication]
//表明当前dump的为设置界面的帧信息,pid为7821
- Total frames rendered: 15
//本次dump搜集了105帧的信息
- Janky frames: 15 (100.00%)
//15帧中有15帧的耗时超过了16ms,卡顿概率为100.00%
- Number Missed Vsync: 3
//垂直同步失败的帧
- Number High input latency: 7
//处理input时间超时的帧数
- Number Slow UI thread: 4
//因UI线程上的工作导致超时的帧数
- Number Slow bitmap uploads: 2
//因bitmap的加载耗时的帧数
- Number Slow issue draw commands: 8
//因绘制导致耗时的帧数
- HISTOGRAM: 5ms=0 6ms=0 7ms=0 ...
//直方图数据,表面耗时为0-5ms的帧数为0,耗时为5-6ms的帧数为0,同理类推。
3.2 使用“GPU呈现模式分析”中的“在屏幕上显示为条形图”选项。**
① 进入Android设备的开发者选项,勾选“GPU呈现模式分析”中的“在屏幕上显示为条形图”选项。
② 操作自己的APP,屏幕上即有相关显示。
4、流量消耗
4.1 使用adb(Linux环境下)
获取进程ID指令
adb shell ps|grep packagename
获取进程ID流量
adb shell cat /proc/pid/net/dev
4.2 使用GT(随身调,腾讯MIG内部)
5、电量消耗
5.1 使用adb
输入命令:
①adb shell dumpsys batterystats PackageName(Android 5.0后引入)
//获取单个应用的耗电量信息
②adb shell dumpsys battery
//获取设备的是否充电,电量,电压等信息
(注:后续可以用battery-historian将输出可视化)
二、性能优化
1、卡顿优化
1.1 原因
- Android系统每隔16ms会发出VSync信号,触发对UI的渲染。所以如果每一帧的绘制时间过长或者主线程太忙,导致VSync信号到来时数据还没准备好,那么两帧的时间内还是显示的同一帧的内容,就会给人卡顿的感觉。
- 举个形象一点的例子,在我们上学的时候我们每天都要交作业,那么我们未能按时完成作业的原因有哪些呢?其实无外乎两种:一种是作业太多,我们在一天内完不成;另一种就是其他事情占用太多时间了,要交作业的时候我们还没能完成。
1.2 优化方案
1.2.1 UI优化:
- 尽量避免多层布局嵌套,使用RelativeLayout
- 在布局层级相同的情况下,优先用LinearLayout
- 将可复用的组件抽取出来并通过<include>标签使用
- 使用<merge>标签减少布局的嵌套层次
- 使用<ViewStub>标签加载一些不常用的布局
- 删除控件中没用的属性
- 尽量避免过度绘制,比如背景经常容易造成过度绘制。由于我们布局设置了背景,同时用到的Material Design的主题会默认给一个背景,这时候应该把主题添加的背景去掉。
- 移除XML文件中非必须的背景。
1.2.2 启动优化:
- 以大化小进行分步加载,耗时操作异步加载,非必需的数据延时加载。
1.2.3 刷新机制合理化
- 尽量减少刷新次数
- 尽量避免后台有高CPU线程运行
- 缩小刷新区域。
2、耗电优化
2.1 原因
在 Android 平台上,由于应用程序可以无限制地注册系统事件(BroadcastReceiver),在这些事件中被不停地唤醒,即使应用已经退到后台,做了很多毫无必要的事情,却导致电量消耗。因此,应用开发者在实现需求的同时,需要尽量减少电量的消耗。
2.2 优化方案
- 合理的使用wake_lock锁。
- 使用jobScheduler2集中处理一些网络请求,有些不用很及时的处理可以放在充电的时候处理,比如图片的处理,APP下载更新等。
- 计算优化,避开浮点运算。
- 数据在网络上传输时,尽量压缩数据后再传输。
- 使用效率高的数据格式和解析方法,建议用FlatBuffer序列化技术,这个比json效率高很多倍。
- 使用Wi-Fi传输数据时,应尽可能增大每个包的大小(不超过MTU)并降低发包的频率。
- 尽量在Wi-Fi环境下使用数据传输。
- 在蜂窝移动网络下,最好做到批量执行网络请求,尽量避免频繁的间隔网络请求,尽量多地保持在Radio Standby状态。
3、安装包大小优化
3.1 原因
应用的安装包越大,用户下载的门槛越高,特别是在移动网络情况下,所以减小安装包大小可以让更多的用户愿意下载和体验产品。
3.2 优化方案
3.2.1 代码混淆优化
- 使用ProGuard设置minifyEnabled 为true。
3.2.2 res资源优化
- 使用Android Lint删除冗余资源。
- 尽量使用一套图片资源,遇到一些图片在不同分辨率手机上变化差异过大的情况时,再考虑在响应文件夹下放入这个特定的图片。
- 使用一套图、一套布局、多套dimens.xml文件,在使用最小资源的情况下,解决多分辨率适配。
- 使用轻量级的第三方库。
- 减少项目中的预置图片,预置图片改成有服务器下发,尽可能的将程序与资源分离。
- 使用WebP格式的图片。
3.2.3 代码优化
- 实现功能模块的逻辑简化。
- 移除无用的依赖库。
3.2.4 lib资源优化
- 一些模块的插件化动态添加。
- so文件的剪裁和压缩。
3.2.5 assets资源优化
- 音频文件最好使用有损压缩的格式,比如采用opus、mp3等格式,但是最好不要使用无损压缩的音乐格式。
4、内存优化
4.1 原因
在 Android 系统中有个垃圾内存回收机制,在虚拟机层自动分配和释放内存,因此不需要在代码中分配和释放某一块内存,从应用层面上不容易出现内存泄漏和内存溢出等问题,但是需要内存管理。Android 系统在内存管理上有一个 Generational Heap Memory 模型,内存回收的大部分压力不需要应用层关心, Generational Heap Memory 有自己一套管理机制,当内存达到一个阈值时,系统会根据不同的规则自动释放系统认为可以释放的内存,也正是因为 Android 程序把内存控制的权力交给了 Generational Heap Memory,一旦出现内存泄漏和溢出方面的问题,排查错误将会成为一项异常艰难的工作。除此之外,部分 Android 应用开发人员在开发过程中并没有特别关注内存的合理使用,也没有在内存方面做太多的优化,当应用程序同时运行越来越多的任务,加上越来越复杂的业务需求时,完全依赖 Android 的内存管理机制就会导致一系列性能问题逐渐呈现,对应用的稳定性和性能带来不可忽视的影响,因此,解决内存问题和合理优化内存是非常有必要的。
4.2 优化方案
4.2.1 内存泄漏优化
- 单例模式中传入的this来源于activity所引起的内存泄漏,可以使用context.getApplicationContext代替。
- Handler引起的内存泄漏。message会持有handler的引用,而非静态内部类的handler会持有外部类activity的引用,这样activity被销毁了但是handler中还有message存在,activity的引用未能及时释放从而造成内存泄漏。可以将handler改为静态内部类,同时activity用弱引用。
- AsyncTask或线程引起的内存泄漏,匿名内部类AsyncTask或Thread会持有外部类activity的引用,activity被销毁了,AsyncTask或者线程还未结束从而引起的内存泄漏。可以将AsyncTask和Thread独立出来或者使用静态内部类,同时activity用弱引用。
- 资源未及时关闭引起的内存泄漏,需要及时关闭cursor,广播接收器、网络连接等资源。
4.2.2 其他优化
- 减少不必要的内存开销。注意自动装箱,增加内存复用,比如有效利用系统自带的资源、视图复用、对象池、Bitmap对象的复用。
- 使用最优的数据类型。比如针对数据类容器结构,可以使用ArrayMap数据结构,避免使用枚举类型,使用缓存Lrucache等等。
- 图片内存优化。可以设置位图规格,根据采样因子做压缩,用一些图片缓存方式对图片进行管理等等。
5、稳定性优化
5.1 原因
Android 应用的稳定性定义很宽泛,影响稳定性的原因很多,比如内存使用不合理、代码异常场景考虑不周全、代码逻辑不合理等,都会对应用的稳定性造成影响。其中最常见的两个场景是:Crash 和 ANR,这两个错误将会使得程序无法使用。
5.2 优化方案
- 提高代码质量。比如开发期间的代码审核,看些代码设计逻辑,业务合理性等。
- 代码静态扫描工具。常见工具有Android Lint、Findbugs、Checkstyle、PMD等等。
- Crash监控。把一些崩溃的信息,异常信息及时地记录下来,以便后续分析解决。
- Crash上传机制。在Crash后,尽量先保存日志到本地,然后等下一次网络正常时再上传日志信息。