写点什么

安卓端贝壳找房 APP 首页滑动卡顿问题的解决

  • 2019-09-23
  • 本文字数:1729 字

    阅读完需:约 6 分钟

安卓端贝壳找房APP首页滑动卡顿问题的解决

1. 背景

在研发初期,打开贝壳找房 app 后上下滑动界面, 明显感觉到顿挫感, 即使在安卓高端机(内存 6G)也如此, 说明不是硬件配置低的锅。

2. 解决思路

造成 UI 卡顿分为 3 方面原因;


CPU 太忙, 即手机运行了很多 app 和服务, 占用了大量的 CPU; CPU 是负责数据运算的, 通过 SurfaceFlinger 告诉 GPU 要显示什么。


GPU 太忙, GPU 接收 CPU 传来的指令, 如果指令太多可能会导致丢帧/卡顿, 渲染一帧图像要在 16ms 以内才能保证 UI 的流畅性;


内存不足, 手机运行太多的 app 和服务,没有充裕内存空间分配到当前 app,但现在市场安卓手机内存主流水平是 3G/4G/6G/8G,一般可以忽略该因素; 但当前 app 占用的内存空间太大可能导致卡顿。 通常是 app 出现内存泄漏或者占用内存太高(例如缓存了图片、文件或其它数据结构)。


PS: 分析 root cause 占用八成时间, 解决问题占用两成时间;


从哪个点入手分析问题???


我的建议是从简单到复杂, 即先分析 GPU 性能(专业叫法是过度绘制,即一个像素被绘制了多次)。


打开 系统设置 — 开发者选择 — 调试 GPU 过度绘制 — 显示过度绘制区域 和 系统设置 — 开发者选择 — GPU 呈现模式分析 — 在屏幕上显示为条形图, 然后再看看要调试的界面;



贝壳找房 App 首页



过度渲染示意图


通过安卓自带功能可以看出首页过度绘制问题很严重, 底部柱状图显示每帧图像渲染时间都超过 16ms, 意味着丢帧/卡段现象比较严重。


那么怎么解决过度绘制问题呢?

3. 问题原理

从叶节点 View/ViewGroup 向上找出所有的父/祖父/曾祖父的 ViewGroup, 一直到布局根节点,删除不必要的背景(设置背景就要多渲染一次);合理调整 UI 布局,尽量减少层级。


删除贝壳找房首页 Activity 的主题背景, 可以在 xml 样式里设置或在 onCreate 里赋空;


确认 Activity 布局根节点 ViewGroup 是否设置背景色, 如果有的话要删除,让子 View/ViewGroup 绘制背景; (减少一次绘制)


判断 Fragment 布局根节点 ViewGroup 是否设置背景色,如果有的话要删除;(减少一次绘制)


首页每个布局卡片是否设置了背景;


像上图显示的推荐房源 ListView 是否设置了背景;


代码里是否有不必要的 notifyDataSetChanged,invalidate,requestLayout 等行为;这都会导致对应 View/ViewGroup 重新绘制;


背景重叠可以通过重写 onDraw 函数, 在缓存 canvas 里绘制完后一次性刷新到界面;



优化后首页


按照如上方式优化后效果很明显, 柱状图基本都在 16ms 以下, 基本满足性能需要,但还是有优化的空间。


这时上下快滑首页还是能感觉到 UI 卡顿, 这时就要分析 CPU 性能了, 即在主线程里是否做了耗时操作; 这时我们可以借助 TraceView 分析每个函数的执行周期; 打开 sdk 的 monitor。



选中要调试的进程, 点击红圈内按钮开始, 再次点击结束; 按照降序排列所有记录。 Parent 表示当前函数被调用的地方, Children 表示当前函数调用的其它函数; 怀疑 MyScrollView 的 handleMessage 在搞事情。



点击


“com.homelink.midlib.view.MyScrollView$1.handleMessage"这一行, 可以看到 handleMessage 函数的执行情况; 可以看到 onScroll 函数执行了 358 毫秒,而且是在主线程, UI 不卡顿等啥呢。



看看 MyScrollView 的 Handler 都做了什么, 就是 sendMessageDelayed 给自己发送个延时消息, 然后就是调用回调了。 继续看看这个 onScroll 都做了什么。


1override fun onSrcoll(scrollY: Int) {2LjExposureUtil.statistics(mExposureCardList, mVisibleList)3mRecommendHouseCard?.childExposure() 4}
复制代码


跟进代码看到 onScroll 就是触发了埋点, 但它是个耗时操作,在滑动过程中会多次执行 onScroll,导致卡顿的问题。


发现问题了, 解决就很简单了。 我们希望的是如丝般顺滑的滑动体验, 那就不要在滑动过程中阻塞主线程, 我们可以在滑动结束时做埋点操作;


1override fun onScrollStop() {2LjExposureUtil.statistics(mExposureCardList, mVisibleList)3mRecommendHouseCard?.childExposure()4}
复制代码


后续工作, 使用 RecyclerView 改造首页。


作者介绍:


高瑞,贝壳找房 Android 工程师,目前负责贝壳找房 app 安卓端研发工作。


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/1380W4dFRSP3KAWJ0lyKnw


2019-09-23 08:002724

评论

发布
暂无评论
发现更多内容

斐波拉契数最小步数与合法括号序列判断

未见花闻

7月月更

iOS 中的 Protocol

NewBoy

ios 前端 移动端 iOS 知识体系 7月月更

基于Qt设计的课堂考勤系统(采用RDS for MySQL云数据库 )

DS小龙哥

7月月更

语音直播app源码

开源直播系统源码

直播系统源码 开源源码 语音直播系统源码

jQuery

Jason199

jquery js 7月月更

记一次uniapp的经历

是乃德也是Ned

uni-app 7月月更

redis安装

想要飞的猪

接口测试进阶接口脚本使用—apipost(预/后执行脚本)

Xd

接口测试

重温算法之颜色分类

自由

算法刷题 7月月更

到底应不应该使用 lombok

HoneyMoose

面试突击65:为什么要用HTTPS?它有什么优点?

王磊

Java 面试题

Qt | 读取文件内容并删除文件 QFile

YOLO.

File 文件操作 qt 7月月更

不习惯的 Vue3 起步五 のapiHooks封装

空城机

Vue3 7月月更

3000字11张图硬核科普:什么是边缘计算?与云计算有什么联系和区别?

wljslmz

云计算 边缘计算 7月月更

密码密钥硬编码检查

Tom(⊙o⊙)

密码 软件安全 信息泄露 静态代码检查 密钥管理

shell脚本定时备份mysql数据库

乌龟哥哥

7月月更

Ceph分布式存储初步认识(一)

Lansonli

私有云 Ceph 云存储 7月月更

查找——顺序表的查找和有序表的查找

乔乔

7月月更

飙车资深老教练-手撸一个EventBus

芝麻粒儿

android EventBus 7月月更

《高绩效教练》:如何用提问激发潜能?

郭明

读书笔记

LeetCode第二题,裂开了..

为自己带盐

LeetCode 7月月更

企业级容器安全风险与最佳实践

明亮安全观

网络安全 安全架构 容器安全

【萌新解题】两数之和

面试官问

LeetCode 哈希表 两数之和

Qt中 connect的多种方式

小肉球

qt 7月月更

OAI L3与L2接口分析

柒号华仔

5G 7月月更

MySQL进阶(一)主外键讲解

No Silver Bullet

MySQL 数据库 7月月更 主外键

读书笔记之数据密集型应用的可靠性

宇宙之一粟

读书笔记 7月月更

zookeeper-认识zookeeper

zarmnosaj

7月月更

Ark UI 中的问题汇总【系列 2】

坚果

HarmonyOS OpenHarmony Open Harmony 7月月更

自定义spring boot starter三部曲之一:准备工作

程序员欣宸

spring springboot 7月月更

安卓端贝壳找房APP首页滑动卡顿问题的解决_文化 & 方法_高瑞_InfoQ精选文章