《Android移动性能实战》一书总结
一、磁盘优化
遵循规则 | 标准 | 优先级 | 规则起源 |
避免主线程I/O | 避免主线程操作文件和数据库 | P0 | 50%以上卡顿问题都是由主线程I/O引起的 |
用apply代替sharePreference.commit | P1 | Apply是异步操作,commit是同步操作 | |
提前初始化sharePreference | P1 | 在多进程和旧版本的Android中,初始化过程的I/O读/写是在主线程的 | |
减少I/O读写量 | 利用缓存减少重复读取 | P2 | 内存缓存命中率极高,投入产出高 |
减少使用select * | P1 | 减少从数据库读取数据量,减少消耗 | |
数据库减少使用autoincrement | P1 | 因为要多操作一个表,所以insert耗时为2-4倍 | |
使用合适的数据库分页 | P0 | Sqlite读/写磁盘是以page为单位的,在3.12.0版本前默认 page size是1kb之后版本后4kb | |
频繁查询的表使用索引 | P0 | 索引可以极大地减少读磁盘的数据量,极大提升效率 | |
避免无有效索引 | P0 | 无效索引的问题通常是严重的,产生大量冗余读写,降低了写入性能 | |
减少I/O操作次数 | 使用8kb buffer读/写 | P0 | 可以减少2-3倍的耗时 |
批量更新数据库使用事务 | P0 | 启用事务,根据业务规则,会大量减少I/O读/写和操作次数,从而提升效率 | |
ZIP压缩大量小文件时建议使用ZipInputStream | P2 |
|
二、内存优化
遵循规则 | 标准 | 优先级 | 规则起源 |
避免内存泄露 | 避免Activity泄露 | P0 | 大部分严重的内存泄露都是Activity泄露,因为 这意味着被引用的View、图片等全部泄露 |
减少常驻型内存 | 尽量使用RGB565 | P1 | 使用RGB565节省图片内存高达50% |
避免内存重复 | P1 | 譬如默认图片内存,提升缓存命中率与流畅度 | |
res/drawable里的图片,建议使用Drawable.createFromStream来加载 | P1 | 使用错误的文件夹,导致图片被放大,最终App 使用的内存增加 | |
将图片放置到合适的资源文件夹(hdpi、xxhdpi等) | P1 |
| |
减少GC | Bitmap尽量使用inBitmap | P1 | 可以减少GC、提升流畅度 |
建议使用SparseArray或者ArrayMap | P2 |
| |
建议使用StringBuilder重用(有线程使用可配合ThreadLocal) |
|
|
三、网络优化
遵循规则 | 标准 | 优先级 | 规则起源 |
避免无效流量消耗 | 避免重复上传与下载 | P0 |
|
JS/CSS/HTML需要进行压缩 | P0 |
| |
使用更优的图片压缩 | P1 | WeP图片下载/展示的速度提升,带宽优化20% | |
前台网络I/O<60kb(要依赖网络下载完成才能展示内容) | P1 | 大于60kb用户体验极差 | |
定时网络请求尽量合并在一个时间进行 | P2 | 无论是4G、3G都有所谓的网络状态机,合并请求可以 让网络尽量处在低功耗的状态 | |
网络请求失败的重试必须有明显的结束条件 | P2 | 会导致严重耗电和服务器压力过大 | |
降低流量风险 | 流量兜底能力 | P0 | 微信发现流量异常会通知服务器终止协议交互,这是 不让问题恶化的好方法 |
四、流畅度
遵循规则 | 标准 | 优先级 | 规则起源 |
界面流畅 | 核心界面必须有流畅度和掉帧率的数据上报 | P0 |
|
FPS平均值大于30,最小值大于24 | P0 | 动画大于24FPS是用户可以接受的最低标准 | |
避免>8的掉帧,尽量减少>4 | P1 |
|
UI卡顿优化点:
1、I/O等耗时操作移动至子线程;
2、透明度对GPU的渲染性能消耗有比较大的影响;
3、避免过多地依赖硬件加速;
4、使用ListView的复用机制+ViewHolder;
5、检测ListView中getView绑定数据是否高效;
6、Measure/Layout耗费一定的时间,避免过多触发layout;
7、避免在View或者Drawable的onDraw里面执行任务繁重的自定义操作;
8、避免过多的垃圾回收;
9、避免UI线程与其他线程持有的锁竞争;
10、对图片进行压缩,编码方式修改RGB_565,ARGB_4444。
五、CPU优化
遵循规则 | 标准 | 优先级 | 规则起源 |
核心场景CPU算法最优 | 建议能用int就不要用float | P2 | 比较两个float数值大小执行时间是int4倍左右 |
选择合适的容器 | P0 | 一般的容器:Vector、HashMap、LinkedHashmap等; Android提供内容稀缺场景使用容器:ArrayMap、SparseArray等; 基于线程安全conCurrentHashMap等 | |
使用缓存和批量预处理来提升算法效率 | P1 | WeP图片下载/展示的速度提升,带宽优化20% | |
充分利用CPU | 根据CPU性能,选择合适的线程数 | P0 |
|
六、电池优化
遵循规则 | 标准 | 优先级 | 规则起源 |
尽量让CPU休眠 | 锁屏、灭屏、程序放置后台时,释放或停止Android涉及耗电的服务 | P1 | 包括GPS、WifiManager、Sensor等 |
锁屏、灭屏释放WakeLock | P0 | 必须释放WakeLock,无论是间接还是直接, 否则会让CPU无法休眠,导致严重的耗电 | |
使用缓存和批量预处理来提升算法效率 | P1 |
| |
避免无端电量消耗 | 程序后台CPU不能连续5分钟且平均超过5% | P0 |
|
七、响应时延
遵循规则 | 标准 | 优先级 | 规则起源 |
界面流畅 | 核心界面必须有响应时延的数据上报 | P0 |
|
启动速度小于2秒 | P0 |
| |
界面切换速度小于500ms | P0 | 时延小于500ms是用户可以接受的最低标准 | |
避免黑屏 | P0 | 黑屏的用户体验最差,可以多种手段避免 |