1,代码优化
- 选择正确的数据结构。Java中常见的数据结构,List,Map以及实现类等。Android也提供了一些数据结构,代替这些类,例如SpareArray可以代替HashMap<Integer, <E>>提高性能
需要注意的是SpareArray不是线程安全的
View的onDraw方法中使用canvas.clipRect来指定绘制区域,防止重叠的组件发生过度绘制
不要使用静态View
资源对象及时关闭
集合对象未清理
及时回收Bitmap对象
及时关闭监听器
不要在XML中声明WebView,在代码中声明
-
handler和内部类的正确用法
- Android中涉及到线程通信就会用到Handler
- 我们知道Handle和Looper,MessageQueue 是一起工作的,在Android中应用启动后会默认创建一个为主线程服务的looper对象,而looper对象用于处理主线程的Message对象,它的生命周期贯穿整个应用的生命周期,主线程的Handler对象会绑定这个looper对象,在主线程创建这个handler对象时,会立即关联looper对象和messageQueue对象,这时发送的message消息就会持有Handler对象的引用
- 非静态的内部类的Handler会持有外部类Activity的引用
-
正确的使用Context
- 单例模式引用非ApplicationContext导致的内存泄露
- 正确的使用Java的引用机制,避免对象强引用造成内存泄露
- 避免重复创建不必要的对象,特别是在循环中
- 对常量使用static final修饰
- 避免内部的getter/setter,根据Android官方文档,在没有JIT编译器的时,直接访问变量速递是getter的三倍,在JIT编译时,直接访问变量时getter的7倍,但是proguard做了优化后,可以做到直接访问变量
2,图片优化
- 图片的格式 ,Android目前支持的有三种:PNG,JPEG,WEBP
- 图片的压缩
- 压缩工具压缩png
- 将图片转为WebP格式
- 使用.9格式的png图片
- 图片的缓存
3,电量优化
- 不需要的时候及时关闭广播接收
- 数据传输-避免传输不必要的数据
- 位置服务-注意更新的频率(综合准确性和电量之间平衡一下)
- AlarmManager 唤醒操作是比较耗电的,通常俩次唤醒的时间间隔不要太短
- Wakelock 是为了保持设备处于唤醒状态的API,即使用户长时间不与设备交互,仍然要保持设备不能进入休眠状态。切记要及时释放锁
4,布局优化
- ViewStub 延时加载
- include 标签共享布局
- merge 当一个布局的最外层是FramLayout,而且这个layout不需要设置background和padding等属性,就可以使用merge代替,减少布局层级
- CompoundDrawable:可以用来代替ImageView+TextView的组合
- 降低布局层级,避免GPU过度绘制
- 使用Hierarchy Viewer 查看布局层级,并且它可以查看其中某个View布局的耗时,measure,layout耗时
- 使用layout inspector查看当前页面布局情况
- lint :不仅可以检查Java代码,而且可以检查布局中可优化的地方
5,网络优化
- 避免DNS解析:缓存IP地址和IP地址不能访问的时候动态更新,以减少DNS解析次数
- 合并网络请求:尽量减少的网络请求次数
- 预先获取数据:需要获取公共数据集中在一个接口,避免重复请求
- 避免客户端轮询
- 优化重连机制:网络请求失败,设置一个最大的重连次数,或者延长重连之间的间隔
- 离线缓存:类似图片,文件缓存到本地,避免重复的网络请求
- 压缩数据大小:二进制代替Json,服务端Gzip压缩,使用WebP图片格式