aosp15/16版本Winscope新特性ViewCapture实战支持

背景:

上一篇文章已经介绍了aosp16版本的Winscope如何编译运行及新版本Winscope的一些新特性。
全网独家干货:aosp/安卓16版本winscope编译踩坑过程及相关新特性介绍

有一个个重要特性就是View Capture,如下图所示:
在这里插入图片描述但是大家有没有想过这个View的层级抓取是所有app默认就有的么?还是说是需要啥额外配置才可以抓取到呢?今天就带大家来实战配置系统app的好View Capture部分的内容,让Winscope可以抓到。

系统应用中的 ViewCapture

ViewCapture 是一种软件工具,用于捕获附加到其挂钩的窗口的视图属性(例如位置、大小、缩放比例和可见性)。ViewCapture 会捕获窗口内各种视图及其属性的相关信息,以便您了解特定时刻的用户体验状态,并跟踪随时间的变化。

屏幕录制可以直观呈现视图在特定时间的状态,并显示其变化情况,但它们需要大量的 CPU 资源,并且可能会影响性能。ViewCapture 工具对资源的影响较小,可以更频繁地启用。此外,ViewCapture 会在视图级别逐帧显示可视化图表,与屏幕录制相比,可更轻松地检查特定时刻的视图状态。

本页面介绍了如何在系统应用中初始化 ViewCapture。

使用

ViewCapture.java 可实现 onDrawListener 的实例,并在绘制过程中收集 ViewCapture 跟踪记录。每次帧重绘都会触发对视图树层次结构的遍历,且从窗口的根视图开始。ViewCapture 使用公共 View.java getter 方法来提取值并将其复制到后台线程,从而提高性能。ViewCapture 实现通过使用 captureViewTree 检查视图是否脏或无效来优化此过程,从而避免遍历整个视图层次结构。captureViewTree 仅适用于系统应用,并且是 UnsupportedAppUsage API 的一部分。此 API 的使用仅限于基于目标 SDK 版本的应用。

限制

以下部分介绍了运行 ViewCapture 时的性能和内存限制。

性能

ViewCapture 性能的主线程平均开销为 195 μs。不过,在最糟糕的情况下,可能需要大约 5 毫秒。请参阅 Perfetto 跟踪记录中的 vc#onDraw 切片。

开销主要源于以下操作:

遍历层次结构需要 50 μs,即使进行修剪也是如此。
从空闲列表分配器中提取对象以存储视图属性副本需要 20 μs。
通过 getter 函数提取每个属性值会导致每个视图进行多次额外的函数调用,耗时 110 μs。
因此,在始终开启跟踪 (AOT) 的情况下启用 ViewCapture 会对系统性能产生负面影响,并导致卡顿。由于存在这些性能和内存限制,因此该方法尚不适用于 AOT。我们建议仅在实验室和本地调试时使用 ViewCapture。

内存

Perfetto 的 ViewCapture 跟踪记录方法使用单个环形缓冲区,该缓冲区具有预定义的内存占用量,可防止过度占用内存。此方法通过避免为每个窗口使用单独的环形缓冲区来避免过度消耗内存,但无法解决针对每个帧在 Perfetto 中存储每个状态的整个视图层次结构的问题。记录单个窗口(例如 NexusLauncher)可能会在 10 MB 缓冲区中生成超过 30 秒的 ViewCapture 数据。不过,从系统界面捕获超过 30 个窗口需要更大的缓冲区或更短的录制时间窗口。

操作说明

请按照以下说明在系统应用中启用 ViewCapture:

将依赖项添加到 Android.bp 文件中,如启动器代码中所示。

android_library {
    name: "YourLib",
    static_libs: [
          ...
        "//frameworks/libs/systemui:view_capture",
          ...
    ],
    platform_apis: true,
    privileged: true,
}

在创建窗口时创建 ViewCapture 实例,例如:

示例 1:

private SafeCloseable mViewCapture;

@Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
}

示例 2:

private SafeCloseable mViewCapture;

@Override
protected void onAttachedToWindow() {
  super.onAttachedToWindow();
  if (enableViewCaptureTracing()) {
      mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
        .startCapture(getRootView(), ".NotificationShadeWindowView");
  }
  ...
}

在销毁窗口时关闭 ViewCapture 实例,如以下示例所示:

示例 1:

@Override
public void onDestroy() {
  ...
  if (mViewCapture != null) mViewCapture.close();
}

示例 2:

@Override
protected void onDetachedFromWindow() {
  super.onDetachedFromWindow();
  if (mViewCaptureCloseable != null) {
      mViewCaptureCloseable.close();
 }
  ...
}

实战成果对比展示

如果不对Activity进行任何startCapture的调用,抓取的Winscope如下:
在这里插入图片描述
明显发现没有任何HelloActivity的View相关的元素。

如果在Activity中进行了startCapture后:
在这里插入图片描述

明显发现可以展示出HelloActivity的View相关的元素。

更多framework相关实战干货,请关注下面“千里马学框架”

在使用ADB Shell执行可执行文件时出现`Segmentation fault`(段错误)通常是由于程序在运行过程中访问了未授权的内存区域或访问了未正确分配的内存地址[^1]。以下是一些可能的解决方案: ### 检查程序代码中的指针操作 段错误通常由指针错误引起,例如访问空指针、越界访问数组或使用未初始化的指针。检查代码中涉及指针的操作,尤其是动态内存分配和释放的部分。使用调试工具(如GDB)可以帮助定位问题,也可以通过生成`core file`来分析崩溃时的堆栈信息[^1]。 ### 使用GDB分析段错误 如果程序在运行时崩溃,可以通过GDB加载生成的`core file`来分析问题。首先确保系统允许生成`core file`,可以通过以下命令设置: ```bash ulimit -c unlimited ``` 运行程序直到崩溃后,使用GDB加载`core file`: ```bash gdb <可执行文件路径> <core文件路径> ``` 在GDB中输入`bt`命令查看堆栈跟踪,定位导致段错误的具体代码位置。 ### 检查可执行文件的ELF结构 段错误也可能与可执行文件的ELF结构有关。ELF文件引入了“Segment”概念,用于将多个属性相似的“Section”合并,以便在装载时映射到进程的虚拟内存地址空间中。确保可执行文件的Segment配置正确,避免映射冲突或越界访问[^3]。 ### 验证ADB连接和设备状态 在执行可执行文件之前,确保ADB连接正常且设备处于开发者模式,并启用了USB调试功能。可以通过以下命令验证ADB状态: ```bash adb kill-server adb start-server ``` 如果显示“daemon started successfully”,则ADB服务已正常启动。连接设备后,执行以下命令确认设备是否被识别: ```bash adb devices ``` ### 检查设备文件系统权限 如果可执行文件需要访问系统文件或目录,确保设备文件系统的权限设置正确。在某些情况下,文件权限不足可能导致段错误。可以通过以下命令进入设备并检查文件权限: ```bash adb shell cd /system/app ls ``` 如果发现权限问题,可以尝试修改文件权限或删除相关文件[^4]。 ### 使用静态分析工具 静态分析工具可以在不运行程序的情况下检测潜在的内存访问问题。使用工具(如`valgrind`)检查可执行文件是否存在内存泄漏或非法内存访问问题: ```bash valgrind --leak-check=yes <可执行文件路径> ``` 这将帮助发现可能导致段错误的潜在问题。 ### 示例代码:使用GDB分析段错误 假设可执行文件为`f16`,运行后生成`core`文件: ```bash ./f16 ``` 使用GDB分析`core`文件: ```bash gdb f16 core ``` 在GDB中输入以下命令查看堆栈跟踪: ```bash (gdb) bt ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值