前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android卡顿分析

Android卡顿分析

作者头像
大公爵
发布2022-11-14 17:16:50
2.4K0
发布2022-11-14 17:16:50
举报
文章被收录于专栏:葬爱家族葬爱家族

一、卡顿原因

屏幕1秒60帧,平均每帧16.6毫秒,如果代码实现不佳,或者过于复杂,导致一帧绘制时间大于16.6毫秒,则无法完成绘制,造成丢帧,连续出现掉帧,在现象上表现为卡顿。

二、App启动时间

1、方法1

代码语言:javascript
复制
adb shell am start -W com.zhoupushuju.zhouyi/com.rnmobx.MainActivity

结果

代码语言:javascript
复制
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.zhoupushuju.zhouyi/com.rnmobx.MainActivity }
Status: ok
LaunchState: COLD
Activity: com.zhoupushuju.zhouyi/com.rnmobx.MainActivity
TotalTime: 931
WaitTime: 934
Complete
  • LaunchState:启动方式,此为冷启动
  • Activity:启动页面
  • TotalTime:启动Activity的总耗时
  • WaitTime:启动Activity的总耗时+少量的系统耗时

2、方法2

代码语言:javascript
复制
adb logcat -b all | grep am_activity_launch_time

结果

代码语言:javascript
复制
[0,78748358,com.zhoupushuju.zhouyi/com.rnmobx.MainActivity,931]

三、AndroidStudio Profile使用

1、在 Android 12 及更高版本上检测卡顿情况

对于搭载 Android 12(API 级别 31)或更高版本的设备,CPU 性能分析器中 Display 窗格下的 Janky Frameworks 轨道中会显示捕获的轨迹。

如需检测卡顿情况,请按以下步骤操作:

  1. 在 Android Studio 中,依次选择 View > Tool Windows > Profiler,或点击工具栏中的 Profile 图标

image.png 如果 Select Deployment Target 对话框显示提示,请选择要将您的应用部署到哪个设备以进行性能分析。如果您已通过 USB 连接设备但系统未列出该设备,请确保您已启用 USB 调试

  1. 点击 CPU 时间轴上的任意位置以打开 CPU 性能分析器。
  2. 从 CPU 性能分析器的配置菜单中选择 System Trace,然后点击 Record。完成与应用的交互后,点击 Stop
  3. 您应该会在 Display 下方看到 Janky frames 轨道。默认情况下,性能分析器只会将卡顿帧显示为有待调查的候选对象。在每个卡顿帧中,红色部分突出显示了相应帧超出其渲染截止时间的时长。

image.png

  1. 发现卡顿帧后,点击该帧;可根据需要按 M 键调整缩放程度以聚焦到所选帧。相关事件会在以下线程中突出显示:主线程、RenderThreadGPU completion

image.png

  1. 通过选中或取消选中 All FramesLifecycle 复选框,您可以根据需要查看所有帧或呈现时间的细分数据。

image.png

2、在Android 11上检测卡顿情况

对于搭载 Android 11(API 级别 30)的设备,CPU 性能分析器的 Frame Lifecycle 部分会显示捕获的轨迹。

image.png

Frame Lifecycle 部分包含层名称和四个轨迹。每个轨迹分别代表帧呈现流水线中的一个阶段。Frame Lifecycle 元素如下:

  1. Frame Lifecycle (层名称):该部分的标题包含用括号括起来的层名称。层是单个组合单元。
  2. Application:此轨迹显示从缓冲区被应用移出队列到重新回到队列的时间。这通常对应于 RenderThread 中的轨迹事件。
  3. Wait for GPU:此轨迹显示 GPU 拥有相应缓冲区的时长。该时长指的是,从相应缓冲区的内容被发送至 GPU,到 GPU 利用相应缓冲区的内容完成其工作,期间所经历的时间。这并不表示 GPU 在此期间仅使用相应缓冲区的内容工作。如需详细了解给定时间内 GPU 执行的工作,您可能需要使用 Android GPU 检查器
  4. Composition:此轨迹显示,从 SurfaceFlinger 占有相应缓冲区并发送相应缓冲区的内容以进行合成,到相应缓冲区的内容被发送到显示屏,期间所经历的时间。
  5. Frames on display:此轨迹显示相应帧在屏幕上的时长。

Frame Lifecycle 部分说明了帧缓冲区在呈现流水线的不同阶段之间的切换方式。帧按帧号进行颜色编码,以便更轻松地跟踪特定帧。

Android Studio 还会在 All Frames 标签页中以表格格式显示轨迹中的所有帧。

image.png

Frame #ApplicationWait for GPUComposition 列表示的数据与上方 Frame Lifecycle 部分的轨迹表示的数据一样。Frame Duration 列表示从 Application 开始到 Frames on Display 开始所经历的时间。这本质上是端到端呈现帧的时长。

您可以按任意列对“Frames”表进行排序,以便快速找到最短或最长的帧。该表还支持分页控件,您可以借助这些控件浏览数以百计的帧。

如需在 Android 11 上检测和调查卡顿情况,请按以下步骤操作:

  1. Application 列对 All Frames 表进行降序排序,使耗时最长的帧首先显示。

image.png

  1. 找到运行时间最长的帧,然后选择表中的一行。这将在左侧的时间轴视图中放大所选的帧。

image.png

  1. Frame LifecycleThreads 部分查找相关线程。

image.png

3、在Android 10及更低版本上检测卡顿情况

对于搭载 Android 10(API 级别 29)及更低版本的设备,相关的操作系统图形管道信息会显示在 CPU 性能分析器系统轨迹中的单个部分,称为 Display

image.png

  • Frames:此部分显示应用中的界面线程和 RenderThread 轨迹事件。时长超过 16 毫秒的事件会以红色表示,以突出显示潜在的卡顿帧,因为它们超出了以 60 帧/秒 (fps) 的速度进行呈现的截止时间。
  • SurfaceFlinger:此部分显示 SurfaceFlinger 处理帧缓冲区的时间。SurfaceFlinger 是负责将缓冲区内容发送到显示屏的系统进程。
  • VSYNC:此部分显示 VSYNC,这是一个表示与显示流水线保持同步的信号。该轨迹会显示 VSYNC-app 信号,这个信号会在应用启动时间过晚时显示。通常情况下,发生这种情况是因为界面线程处于忙碌状态。在动画播放期间,它会导致屏幕上出现可见的闪烁,并且在动画或滚动完成之前,会持续带来额外的输入延迟。对于刷新率较高的显示屏,尤其要注意查看该轨迹,因为与刷新率为 60 次/秒或刷新率可变的显示屏相比,这种显示屏更容易出现此类问题。
  • BufferQueue:此部分显示有多少帧缓冲区在排队等待 SurfaceFlinger 使用。对于部署到搭载 Android 9(API 级别 28)或更高版本的设备的应用,此轨迹显示应用 surface BufferQueue 的缓冲区计数(012)。BufferQueue 可帮助您了解图像缓冲区在 Android 图形组件之间切换时的状态。例如,值 2 表示应用当前处于三重缓冲状态,这会导致额外的输入延迟。

Display 部分会提供有助于检测潜在卡顿的实用信号,例如何时界面线程或 RenderThread 的用时超过 16 毫秒。若要调查导致卡顿的确切细节,您可以查看 Threads 部分,其中会显示与界面呈现有关的线程。

image.png

在上图中,Threads 部分显示了界面线程 (java.com.google.samples.apps.iosched)、RenderThreadGPU completion 线程。这些线程与界面呈现有关,可能是导致卡顿的原因。

如需在 Android 10 或更低版本上检测卡顿情况,请执行以下操作:

  1. 查看 Display 中的 Frames 轨迹。红色帧是要调查的候选对象。

image.png

  1. 发现可能存在卡顿的帧后,请按 W,或在按住 <kbd style="box-sizing: inherit;">Control</kbd> 键(在 macOS 设备上,则按住 <kbd style="box-sizing: inherit;">Command</kbd> 键)的同时滚动鼠标滚轮,以便进行放大。继续放大,直到您看到界面线程和 RenderThread 中的轨迹事件。

image.png 在上图中,Choreographer#doFrame 显示了界面线程何时调用 Choreographer 来协调动画、视图布局、图像绘制和相关进程。DrawFrames 显示了 RenderThread 何时形成并向 GPU 发出实际绘制命令。

  1. 如果您发现某个轨迹事件特别长,可以进一步放大,以便找出可能导致呈现速度缓慢的原因。上图显示了界面线程中的 inflate,这意味着应用正在花时间膨胀布局。当您放大其中一个 inflate 事件时,可以确切了解每个界面组件花费的时间,如下所示。

image.png

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、卡顿原因
  • 二、App启动时间
    • 1、方法1
      • 2、方法2
      • 三、AndroidStudio Profile使用
        • 1、在 Android 12 及更高版本上检测卡顿情况
          • 2、在Android 11上检测卡顿情况
            • 3、在Android 10及更低版本上检测卡顿情况
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档