尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

android滑动卡顿

android滑动卡顿 每一帧指标是 16.6ms超过这个 数就会掉帧 → 用户感觉「卡」有很多原因会导致一般是主线程过多ui绘制大量IO操作占用cpu用户滑动 / 界面刷新时每一帧大致是VSYNC 信号到了↓Choreographer#doFramemain 线程↓Input / Animation / Traversal / Draw 等回调↓traversal measure → layout → draw遍历 View 树↓把绘制命令交给 RenderThread↓GPU 合成上屏profile工具看卡顿通过 profile 工具里的System Trace 工具 查看 分析可以人为的在自己对应代码上打上 标签Trace.beginSection/endSection 给代码打时间标签System Trace 里出现自定义色块用来量「这一段inflate、bind、初始化等花了多少 ms」弥补系统 trace 看不到 App 业务逻辑的问题如图先勾选对应处你可以在 AllFrames中看到录制这段时间对应每一针的对应的时间然后你对左侧AllFrames中颜色区域你可以点对应的每一针右侧显示对应数据我们现在对每一针显示的数据进行概念分析Jank type掉帧类型总共有三种No jank 准时完成Actual ≤ ExpectedDeadline missed 掉帧该上屏的时间到了帧还没准备好 → 严重迟到Buffer stuffing 帧缓冲/流水线积压帧 晚到或排队Layer name 这一帧到底是哪个界面上的Actual duration 实现消耗时间Expected duration 预算期望时间Main thread states每项是什么Running 表示 CPU 正在执行 Main代码其中onCreate、measure、layout、draw、等时间Sleeping 表示 Main 线程 主动睡眠如 Thread.sleep、等消息、Looper 空闲等Waiting 表示 等锁 / 等别的线程synchronized、阻塞 IO 等Runnable 表示 main线程正在等待cpu调度cpu 正在忙其他线程当你的Main线程中的 Running过大代表你的 onCreate measure、layout、draw等 其实就是你的计算逻辑过复杂当你的Main线程中的 Sleeping 过大可能是一直处于睡眠中当你的Main线程中的 Waiting过大main 被堵住在等锁或别的线程查主线程阻塞锁竞争、同步 IO、跨线程 wait。当你的Main线程中的 Runnable考虑线程是否占满核、系统负载高RenderThread states 中 Running 过大 可能是过度绘制比如是 ui层级复杂大图Actual 大 Main Running 大 → 主线程 UI/业务重layout、onCreate、bindActual 大 Main 小 Render 大 → 绘制重Actual 大 Main/Render 都不大 → Deadline missed / 等 VSYNC / 合成 / 启动被堵Actual 小 都小 → 正常帧如 2.96ms一些布局写法优化方案AsyncLayoutInflater普通 LayoutInflater.inflate() 在 主线程 执行读 XML → 解析节点 → new View → 递归创建子 View 一次次反射耗时获取对应的view布局嵌套过多就越耗时可以使用 AsyncLayoutInflater 他本质就是创建个子线程在子线程中 解析 XML、创建 View 树创建后在通过Handle 把view返回给 主线程去 addView让主线程去绘制 measure / layout / draw这个view基本使用AsyncLayoutInflater(this).inflate(R.layout.heavy_item,parent,// 可为 null不为 null 时会带上 LayoutParamsobject:AsyncLayoutInflater.OnInflateFinishedListener{override funonInflateFinished(view:View,resid:Int,parent:ViewGroup?){// 已在主线程parent?.addView(view)// 或交给 RecyclerView ViewHolder 使用}})注意AsyncLayoutInflater只是节省了inflate 反射 的时间但是addview 上屏幕的 measure / layout / draw 仍在主线程ViewStubViewStub 是一个轻量级View他不可见是先占位只有设置ViewStub为visible或者调用其inflate起对应的view才会被初始化merge 标签当我们有一些布局需要被多处使用我们可以把他抽成一个单独的布局文件在需要的地方通过include加载
返回列表