- 数据结构的选择
安卓提供了SparseArray,SparseIntArray,SparseLongArray,SparseBooleanArray
适用Integer到Object的映射。核心实现是二分查找法,所以适用的是数据量比较少的情况。 - Java的四种引用方式
强引用:用的最多的一种,对象默认的引用类型。如果一个对象具有强引用,那么垃圾回收器不会对它进行回收操作。当内存不足时就会抛出OutOfMemoryError错误。
软引用:一个对象如果只有软引用的话,当内存充足的时候Gc不会对它进行回收,当内存紧张的时候才会被回收。如果配合引用队列ReferenceQueue使用的话,当软引用指向的对对象被回收后,Java虚拟机将会把这个引用加入到与之关联的引用队列中。
弱引用:弱引用也是用来描述非必须对象的,他的强度比软引用更弱一些,被弱引用关联的对象,在垃圾回收时,如果这个对象只被弱引用关联(没有任何强引用关联他),那么这个对象就会被回收。
虚引用:虚引用和弱引用和软引用都不两只,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象的实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。虚引用和弱引用对关联对象的回收都不会产生影响,如果只有虚引用活着弱引用关联着对象,那么这个对象就会被回收。它们的不同之处在于弱引用的get方法,虚引用的get方法始终返回null,弱引用可以使用ReferenceQueue,虚引用必须配合ReferenceQueue使用。 - 正确使用内部类
在Java中一个非静态内部匿名类会持有外部类的一个隐式的引用,这样就可能会导致外部类无法被正常回收。
主要分两种情况:
(1)耗时或者延时操作,在外部类回收时候,内部类还有未完成的操作。
常见的有Handler,动画等
Handler的正确使用:1、使用静态内部类+弱引用;2、页面回收调用removeCallbacksAndMessages();
动画也应该是页面回收前释放掉。
(2)常见的单例的静态变量持有内部类。 - UI优化
卡顿:每秒钟刷新60帧,约16ms刷新一次,如果逻辑复杂、内存不足、CPU耗时、GPU耗时大于16ms,UI就无法完成一次绘制,那么就会造成卡顿。主要原因有以下几点:
(1)过度绘制
(2)CPU资源不足
(3)频繁的 GC
优化方案:
(1)按情况选用<merge><include><ViewStub>
(2)尽量减少UI的嵌套层次
(3)减少透明色的使用
(4)去除不必要的背景
(5)onDraw中不要实例化过多对象或者做耗时操作,因为onDraw会频繁被调用,实例化对象可能会导致内存抖动
(6)避免过度绘制,不可见时候不用绘制。
优化工具:
(1)Layout Inspector。AS-Tools-Layout Inspector
(2)Lint;AS-Analyze-Inspect Code...
(3)手机自带的GPU过度绘制显示工具。
(4)BlockCanary检测UI卡顿 - 内存优化
(1)内存泄漏;当一个对象已经不需要再使用,本应该被回收,而另一个正在使用的对象持有它的引用,导致对象无法被正常回收。
--1、正确使用内部类
--2、设置监听与取消监听成对出现
--3、及时释放资源,比如I/0读写,数据库,动画
--4、正确选用引用类型
--5、单例或者静态变量里的引用
--6、正确使用Context
(2)内存抖动;在循环语句中创建临时对象或者在绘制时配置大量对象或者执行动画时创建大量临时对象
内存抖动会带来UI的卡顿,因为大量的对象创建,会很快消耗剩余内存,导致GC回收,GC会占用大量的帧绘制时间。
--1、避免在循环里创建对象
--2、避免在iew的onDraw()方法里创建对象,该方法会被频繁调用。
--3、Bitmap三级缓存
(3)内存溢出;Android应用程序在运行时都有一定的内存限制,当内存到达阀值后再去申请不到内存就会溢出。
--1、内存泄漏是导致内存溢出的最大原因,要处理好泄漏问题
--2、Bitmap压缩,webp格式,三级缓存等
--3、选用更合适的数据结构来减少内存开销
--4、少用枚举,枚举会占用更多的内存从反编译的代码来看,我们定义的枚举,编译器会将其转换成一个类,这个类 继承自java.lang.Enum类,除此之外,编译器还会帮我们生成多个枚举类的实例,赋值给我们定义的枚举类型常量,并且还声明了一个枚举对象的数组,保存了所有的枚举对象。可以用接口常量加@IntDef实现,请参考View.SetVisibility()方法
--5、对常量使用static final修饰
--6、谨慎使用依赖注入框架,因为会加载一些你不需要的东西,很久才会释放。
--7、重写Activity和Application的onTrimMemory()方法,当界面不可见的时候适当的释放内存,然后在这个方法中监听TRIM_MEMORY_UI_HIDDEN这个级别,一旦触发说明用户离开了程序,此时就可以进行资源释放操作了。
--8
(4)内存分配:具体请看https://mp.weixin.qq.com/s/UGoa_H2Wyw7gT9bYXOaMt
(5)优化工具:LeakCanary是一个内存泄漏检测工具。Android Monitor导出Android HPROF文件分析
- 电量优化
1、及时关闭一些无用的监听,比如广播,传感器
2、位置服务的优优化,比如频率
3、使用WakeLock时,需要切记及时释放锁,而且通常情况下,要尽早地释放WakeLock:
4、网络请求之前,检查网络连接。没有网络连接不进行请求。
- 网络优化
1、可以考虑换用Google推出的Protocol Buffer。
2、使用Gzip来压缩request和response,减少传输数据量,从而减少流量消耗。
3、网络缓存。
4、对一些不需要实时提交的数据做延时打包上传。
5、重试机制优化。
6、用JobSchedule监听WIFI、充电等条件再做一些耗电,耗流量的操作。