整理自网络
Android性能 - 启动
- Android程序的启动分类
- 冷启动
- 加载启动app
- 展示空白window页面
- 创建app进程
- 创建app对象
- 启动主线程
- 创建启动activity对象
- 加载view
- 布置屏幕
- 第一次绘制
- 启动优化方向
- 替换window页面背景 <障眼法>
- 避免启动的密集初始化
常常使用的multiDex初始化,第三方组件初始化
利用欢迎页和闪屏页时间完成初始化 - 避免耗时操作和深嵌套布局
Android性能 - 布局
由于任何原因导致接收到VSYNC信号的时候无法完成本次刷新操作,就会产生掉帧的现象
- 过度绘制
- 解决
- 去掉布局的背景色
- 去掉不必要控件的背景色
- GPU渲染
- 橙色 :GUP做的任务
- 红色 :绘制视图的多少
- 浅蓝色 :绘制图片
- 深蓝色 :更新视图
- 绿色1 :布局测量
- 绿色2 :动画
- 绿色3 :输入处理
- 深绿色: 主线程耗时操作
Android性能 - 内存 (一)
- Java内存
- 方法区:常量,类信息 <线程共享>
- 虚拟栈:每个方法由栈帧,存储方法信息 <线程私有,为Java方法服务>
- 本地栈:为本地方法服务
- 堆: 对象实例所在<线程共享>
- 程序计数器: 所执行的字节码行号指示器 <Java方法拥有,本地方法为空>
- Java内存回收
- 标记清除 : 标记回收对象,清除被标记对象 <易产生大量碎片>
- 复制算法 :内存一分为二,一个现用,一个备用 <实际可用内存大小缩小为一半>
- 标记整理: 标记回收对象,整理(移动)存活对象 <避免内存碎片,避免一半内存的浪费 针对对象存活率较高的老年代>
- 分代收集: 根据对象的生命周期划分内存
堆:
新生代 ->大量对象死亡 -> 复制算法
老年代 ->对象存活率高 -> 标记算法
- 对象是否回收
- 引用计数
引用对象,计数+1
引用失效,计数 - 1
缺点:不能解决相互循环引用 - 可达性分析
以GCroot对象为根节点
有可达引用链表示对象存活
- Android内存
- Dalvik虚拟机
- 加入JIT即时编译策略: 缺点①每次启动应用都要编译②运行时更耗电
- ART虚拟机
- AOT编译策略,静态编译,安装程序的时候编译
- 改进GC过程
- 两者混合编译
- 程序安装时dex不会被编译
- 运行时编译dex
- 手机充电或者空闲时进行AOT编译
- 内存回收
新生代->老年代->永久代 - 共享内存
Zygote的进程fork出来的程序进程 - 分配和回收内存
Android性能 - 卡顿
60帧合适的显示速度,16ms内显示界面布局表示流畅画面
卡顿时候,帧率下降到30等,很明显的卡顿
卡顿的原因
- UI线程中的耗时操作
- I/O读写
- 数据库访问
- 网络请求
- 布局不合理
- 控件数量多
- 嵌套深
- overdraw
- 内存异常
- 内存泄漏
- GC次数多 <那么CPU绘制时间就短>
- 错误的异步操作
- 异步线程开启失误
寻找卡顿原因
- stick mode
检测程序中违例的情况
- 主线程进行I/O操作
- 主线程进行网络请求
主要检测两大问题
- 线程策略 <线程使用不当>
- VM策略 <内存泄漏>
使用
在debug模式下使用
查看日志
Android性能 - 异步
异步不包治百病,不正确使用异步会更卡顿
线程调度
- nice values线程优先级
- default UI线程
- background 后台线程
- cgroups
- 控制和分离进程组
- 使用
IntentService
ThreadPoolExecutor
Android性能 - 瘦身
- APK组成
- assets/ 静态文件
- lib/ os文件
- META-INF/ 签名信息
- res/ 资源文件
- AndroidManifest.xml 配置文件
- classes.dex Java字节码的产物
- resource.arsc 编译后的二进制资源文件
- AS自带的 analyze APK工具
- 反编译工具 class shark
https://github.com/google/android-classyshark/releases - 如何瘦身
- 移除无用代码
- 移除无用库,相同库
- 启用Proguard
稍用,规则繁琐 - 缩减方法数
- 移除无用资源
- 图片压缩
压缩网站 https://tinypng.com/
AndroidStudio插件:TinyPngPlugin,能够批量地压缩项目中的图片,更加方便。 - png转jpg
png无损
png体积大 - 使用矢量图
xml, svg - 使用webp
- 网络资源
- so文件瘦身
- 使用7zip进行极限压缩
Android性能 - 电量
- 工具 Battery Historian
- 电量优化
- CPU时间片
- 网络传输
数据压缩
传输方式
请求处理
无网避免请 - GPS
合适的location provider
及时注销监听
模块复用
- wake lock 不休眠锁
- 传感器
Android性能 - 网络
- 网络问题
- 流量消耗
- 电量消耗
- 热修复
- 弱网
- 网络监控
- network monitor 网络请求
- fiddler charles 抓包
- 优化方向 <速度,流量,成功率>
- gzip压缩减少传输
- IP直连去除DNS解析
- webp格式的图片
- 缩略图
- 网络缓存
- 弱网判断特殊处理
Android性能 - 无响应
- 分类
- 触摸或按键等待
- 广播不能规定完成
- 服务不能规定完成
- 原因
- 主线程阻塞
- IO等待
- 其他程序影响
- 出发场景
- 输入5s未响应完毕
- 前台广播10s内未完毕,后台20s
- 前台服务20s,后台服务200s
- 内容提供者publish 10s
Android性能 - Bitmap
- bitmap内存模型
Android2.2之前GC执行,主线程暂停;
Android2.3之后,GC并发执行
API 10 bitmap像素数据存放在 native内存,对象在dalvik heap;
3.0~8.0 像素和对象都在native内存;
8.0~now 像素又移到了native,对象和像素可以同时回收,新增hardware bitmap - bitmap回收
2.2.3之前推荐使用bitmap.recycle()
3.0之后复用bitmap
- bitmap的复用
- bitmap的加载
- 推荐使用图片加载框架glide,piccasso等处理图片