Android performance optimization

一、理由

对于一个app,如果用户使用过程中出现卡顿,反应迟缓,直至最后anr,用户会很耐烦,直至卸载app,从而转向竞品。在迭代开发中,开发者一般忙于需求完成,或多或少的会忽略app的性能,这就要求平时我们写代码过程中多思考。在需求少的版本中加入对app的一些性能优化,提升用户体验。

二、性能指标检查项等

启动速度,启动项不可过多。一般app开发者会把例如云盾,友盟,听云之类的,或者自己的组件lib的初始化,串行的罗列在application的oncreate方法中。这样串行会极大的影响app启动速度,所以在之前一个版本中,我们加入了线程池初始化,区分出来了必须执行和不需要执行(app启动到主页面必须初始化的lib)等组件,减少启动过程中的耗时。

2.界面切换:应用操作时,界面和动画不应有明显卡顿;这时候我们可通过在手机上打开 设置->开发者选项->调试GPU过度绘制,然后操作应用查看gpu是否超线进行初步判断;

内存泄露:按返回键退出不应存在内存泄露,简单的检查办法是在退出应用后,用命令adb shell dumpsys meminfo 应用包名查看Activities Views是否为零;也可以采用第三方app LeadCanary,如果有内存泄漏,会在通知栏弹窗泄漏的地方。

过度绘制:打开设置中的GPU过度绘制开关,各界面过度绘制不应超过2.5x;也就是打开此调试开关后,界面整体呈现浅色,特别复杂的界面,红色区域也不应该超过全屏幕的四分之一

反射优化:在代码中减少反射调用;对频繁调用的返回值进行Cache等

稳定性:连续48小时monkey不应出现闪退,anr问题;如果应用接入了数据埋点的sdk,比如百度统计sdk等,这些sdk都会将应用的崩溃信息上报回来,开发者应每天关注这些统计到的崩溃日志,严格控制应用的崩溃率;

耗电:应用进入后台后不应异常消耗电量;操作应用后,退出应用,让应用处于后台,一段时间后通过adb shell dumpsys batterystats查看电量消耗日志看是否存在异常。

三、性能问题常见表现

UI卡顿和稳定性:这类问题用户可直接感知,最为重要;

内存问题:内存问题主要表现为内存泄露,或者内存使用不当导致的内存抖动。如果存在内存泄露,应用会不断消耗内存,易导致频繁gc使系统出现卡顿,或者出现OOM报错;内存抖动也会导致UI卡顿。

耗电问题:会影响续航,表现为不必要的自启动,不恰当持锁导致系统无法正常休眠,系统休眠后频繁唤醒系统等;

四、性能问题常见原因分析

1.卡顿常见原因

1)人为在UI线程中做轻微耗时操作,导致UI线程卡顿;

2) 布局Layout过于复杂,无法在16ms内完成渲染;

3)同一时间动画执行的次数过多,导致CPU或GPU负载过重;

4) View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重;

5) View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染;

6) 内存频繁触发GC过多(同一帧中频繁创建内存),导致暂时阻塞渲染操作;

7) 冗余资源及逻辑等导致加载和执行缓慢;

8)工作线程优先级未设置为Process.THREAD_PRIORITY_BACKGROUND 导致后台线程抢占UI线程cpu时间片,阻塞渲染操作

解决办法:

1)解决过度绘制问题

在设置->开发者选项->调试GPU过度绘制中打开调试,看对应界面是否有过度绘制,如果有先解决掉:

定位过渡绘制区域

利用Android提供的工具进行位置确认以及修改(HierarchyView , Tracer for OpenGL ES)

定位到具体的视图(xml文件或者View)

通过代码和xml文件分析过渡绘制的原因

结合具体情况进行优化

使用Lint工具进一步优化

检查是否有主线程做了耗时操作:

严苛模式(StrictMode),是Android提供的一种运行时检测机制,用于检测代码运行时的一些不规范的操作,最常见的场景是用于发现主线程的IO操作。应用程序可以利用StrictMode尽可能的发现一些编码的疏漏。

开启 StrictMode

对于应用程序而言,Android 提供了一个最佳使用实践:尽可能早的在

android.app.Application 或 android.app.Activity 的生命周期使用 StrictMode,onCreate()方法就是一个最佳的时机,越早开启就能在更多的代码执行路径上发现违规操作。如果主线程有网络或磁盘读写等操作,在logcat中会有"D/StrictMode"tag的日志输出,从而定位到耗时操作的代码。

3)如果主线程无耗时操作,还存在卡顿,有很大可能是必须在UI线程操作的一些逻辑有问题,比如控件measure、layout耗时过多等,此时可通过Traceview以及systrace来进行分析。

2.内存泄露

该问题目前在项目中一般用leakcanary基本就能搞定,配置起来也相当简单:一旦有内存泄露,将会在通知栏生成一条通知,点开可看到泄露的对象以及引用路径

3.内存抖动

如果代码中存在在onDraw或者for循环等多次执行的代码中分配对象的行为,会导致运行过程中gc次数增多,影响ui流畅度。一般这些问题都可通过lint工具检测出来。

4.耗电量优化建议

电量优化主要是注意尽量不要影响手机进入休眠,也就是正确申请和释放WakeLock,另外就是不要频繁唤醒手机,主要就是正确使用Alarm。

使用优化过的数据集合

谨慎使用抽象编程

尽量避免使用依赖注入框架

很多依赖注入框架是基于反射的原理,虽然可以让代码看起来简洁,但是是有碍性能的。

谨慎使用external libraries

优化整体性能

使用ProGuard来剔除不需要的代码

五、总结

以上就是一些常见的性能分析问题,我们平常的编过程,要多从以下几个方面思考

了解编程语言的编译原理,使用高效编码方式从语法上提高程序性能;

采用合理的数据结构和算法提高程序性能,这往往是决定程序性能的关键;

重视界面布局优化;

采用多线程、缓存数据、延迟加载、提前加载等手段,解决严重的性能瓶颈;

合理配置虚拟机堆内存使用上限和使用率,减少垃圾回收频率;

合理使用native代码;

合理配置数据库缓存类型和优化SQL语句加快读取速度,使用事务加快写入速度;

使用工具分析性能问题,找出性能瓶颈;

你可能感兴趣的:(Android performance optimization)