结合KaDa故事谈谈Android 性能优化
稳,运行要稳
我们的目标,不是没有蛀牙,而是无泄漏,低crash
内存泄漏与溢出
- 属性动画导致的内存泄漏(归根结底是匿名类持有外部类引用导致的)
- 第三方支付导致的内存泄漏(几个PayController采用了静态的HashMap做缓存)
- WebView导致的内存泄漏
降低Crash率
NullPointerException
保护系统提供的API关键方法进行
try catch
保护第三方库的API关键方法进行
try catch
保护(X)RecyclerView使用问题(坑点)
- 默认动画
- 下拉刷新
- onDetachView() 类路径名报名不一样导致找不到
- 下拉刷新动画造成内存泄漏
- 不足一屏会出问题
监测指标及工具方法
指标
- 从启动到MainActivity的内存(天猫精灵)
- 内存抖动(内存抖动离谱的话,会导致OOM发生)
- 内存回收(操作一定时间后回到初始页面内存的使用情况(天猫精灵))
工具方法
- 用我们那锐利的双眼
- LeakCanary(已经使用)
- Android Studio Profile的使用
- adb shell dumpsys 命令(神器)
快,运行要快
让用户体验丝般顺滑
降低ANR
首当其冲的时降低ANR的发生
UI优化
监测工具
Android Studio->Tools->Layout Inspector
开发者选项中的Overdraw
开发者选项中的GPU呈现模式分析,或如下命令:
1
adb shell dumpsys gfxinfo com.hhdd.kada
布局优化
- 尽量避免RelativeLayout的使用
- RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure(区分下weight=0的情况)
- RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin
- 选择性使用ViewStub
- ImageView的中的
src
在xml中能不设置就不设置,如果可以请动态设置 - merge和include的使用
- ConstraintLayout用起来
- 结合了LinearLayout和RelativeLayout的优点
- 圆形相对定位
- 可见性行为约束(不至于View一被设置成Gone这个UI就垮掉)
- 宽高比约束
- Chain(实现LinearLayout
layout_weight
能达到的效果,有过之而无不及) - 提供了虚拟视图(为什么叫虚拟视图,自行查看源码)
- GuideLine,参考线,解决对齐问题神器
- Barrier,解决对齐问题,特别是一些输入表单
- Group,顾名思义,对View进行分组,统一设置其可见性(之前需要把他们放在一个ViewGroup中来进行可见性管理,无形中增加了布局层级)
绘制优化
主要是自定义View
主要注意以下两点:
- 避免onDraw中局部变量的创建;(onDraw函数执行会比较频繁,会造成内存抖动,内存抖动就加剧了GC的发生,会造成卡顿)
- 避免onDraw中循环的使用
Fragment懒加载用起来
目前KaDa故事App主页面好像没有利用Fragment的懒加载,带来的问题(一打开页面,三大模块的网络请求齐头并进),对App的流畅性
以及启动内存
都有影响
加快启动速度
主要是冷启动的速度,因为与暖启动和热启动相比,冷启动的时间确实有点久
冷启动主要分两个部分:
应用的创建(Application)
- 加载并启动应用程序
- 启动后立即显示应用程序的空白启动窗口
- 创建应用程序进程
主Activity的创建:
- 启动主线程
- 创建主Activity (这里指的是LaunchActivity)
- 加载布局
- 屏幕布局
- 执行初始绘制
- 应用程序进程完成第一次绘制后,系统进程会交换当前显示的背景窗口,将其替换为主活动
小,身材苗条
包体小百分之五,可能新增就增加百分之五(引用自网络,不知道是不是真的)
apk构成
AndroidManifest.xml文件
assets目录,里面的资源原封不动的打包到apk的,能压缩压缩
.dex文件,降低方法数,有可能减少.dex文件的个数
libs,so文件的选择性支持
res,无用资源的即时清除,Android Studio ->Refactor->Remove unused resources
混淆配置
这个过程中涉及到第三方库资源的时候需谨慎删除
降低方法数
方法数查看方法,利用dexCount
- 减少不必要的第三方库引用
- 避免重复的功能库引用
- Android studio ->Analyze 用起来
省,省电、省流量、省心
流量已经很廉价,主要是省电和省心
耗电量过大,可能回导致用户卸载App
- 需要进行网络请求时,我们需先判断网络当前的状态。
- 在多网络请求的情况下,最好进行批量处理,尽量避免频繁的间隔网络请求。
- 在同时有wifi和移动数据的情况下,我们应该直接屏幕移动数据的网络请求,只有当wifi断开时在调用,因为,wifi请求的耗电量远比移动数据的耗电量低的低。
- 后台任务要尽可能少的唤醒CPU。(比方说,锁屏时,QQ的消息提示行就是唤醒了CPU。但是它的提示只有在你打开锁屏或者进行充电时才会进行提示。)
其他
编写高效代码的两个基本原则(摘自网络):
- 不要做你不需要做的工作
- 如果可以避免,请不要分配内存