DeepAndroid打算把这些年业务上做的东西好好总结下
1、常规操作
(1)布局优化
- 层次减少:merge、viewStub懒加载、减少多余层次(有其他文章说在item里面使用ConstraintLayout会有性能问题,目前我没碰到,可能高版本优化了)
- view的个数减少: textview的span来替换、无用的view
- view能确定大小尽量写死,避免measure:图片大小、item的高度
- 避免过渡绘制: backgroud重叠可以去掉无用的
- 减少inflater时间:方便代码写的布局可以替换xml(说是这么说,但是往往手写代码布局确实没有xml开发效率高,扩展和维护性好, goole出了个Jetpack Compose,后面看下原理,性能如何)
(2) cpu密集型操作 异步化
- onBindViewHolder里面的数据直接用于展示, 避免有cpu密集型操作,例如:时间格式转化、解析表情、json解析等
(3)避免频繁new对象,消耗资源,触发gc可能频繁回收
例如 addXxListener根据 ID 来进行不同的操作,不要每次new XxListener
(4) 滚动过程中停止其他线程,避免和主线程竞争cpu资源
停止load图片(如果产品接受)
2、其他优化(之前我没做过的)
(1)diffUtil 的更新
diffUtil得用法,可以自己去网上搜,我的心得总结
- 目前针对insert尾部添加数据和update 数据 确实性能比 全部notifydatachange更新渲染的帧率要好;
- 但是在头部insert数据,diffutil触发的更新 有一些多余的刷新recyclerView操作,导致渲染的帧率并不好,这个地方还在 跟踪原因;
- 另外diffUtil的计算最好放到异步线程,避免随着数据变多,计算变慢;
diffUtil确实提高刷新帧率,如果你想精细化到每个字段对应ui的diff变动,确实有一定开发成本,如下:
- 你得手写字段是否相等逻辑,然后payloads里面读取 变化得字段 触发对应字段得ui刷新(这个过程后面我打算用字段反射和数据动态绑定来简化这个过程)
- 新数据集合的对象得重新new一个,即使是一个字段值改变了(例如:你消息列表中,一个消息的状态变成发送成功了,你得重新new个新对象,然后把state改成成功,这样才能diff 新旧对象里面state字段值不一样,才会触发刷新stateView)
(2)扩大recyclerView的viewholder的缓存池,以空间换时间
例如在消息列表中, 文字和图片两种type的 viewholder使用最多,所以我就针对这两种type,扩大到10个,默认是5个
RecyclerView.recycledViewPool.setMaxRecycledViews(int viewType, int max)
(3)如果是多个tab的形式,可以公用一个recyclerView的recycledViewPool缓存池,这样切tab可以更快
(4)性能更好的自定view组件
- 自定义textview( 暂时没有做到,因为textview里面还嵌套了gif表情)