博客
关于我
开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
阅读量:155 次
发布时间:2019-02-27

本文共 2648 字,大约阅读时间需要 8 分钟。

发布app后,开发者最头疼的问题就是如何解决交付后的用户侧问题的还原和定位。传统的用户反馈方式主要有文字输入或视频录制两种,但都存在效率低、复现困难等问题。为了解决这些痛点,闲鱼技术团队结合自身业务需求,在Flutter平台上提出了一套全新的技术方案,实现了用户反馈问题的全流程解决。

背景

目前的app普遍提供用户反馈入口,但现有反馈方式存在以下问题:

  • 文字或截图输入耗时费力
  • 开发者难以准确理解反馈内容
  • 线下无法复现问题
  • 视频反馈无法定位问题

针对这些问题,我们设计了一套全新的用户反馈问题回放体系,通过抓取UI事件流和业务数据,利用事件回放机制实现问题复现。

Flutter手势基础知识

要实现UI手势事件的录制与回放,首先需要理解Flutter手势系统的基本原理。

1. Flutter UI触摸原始数据Pointer

Flutter中的手势系统可以分为两层概念:

  • 原始触摸数据(Pointer):描述触摸事件的时间、类型、位置和移动。
  • 手势:由一个或多个原始触摸数据组成的语义动作。

Flutter接收Native传来的原始数据通过以下接口:

void _handlePointerDataPacket(ui.PointerDataPacket packet) {    _pendingPointerEvents.addAll(PointerEventConverter.expand(        packet.data, ui.window.devicePixelRatio));    if (!locked) _flushPointerEventQueue();}

2. 手势决议机制

Flutter通过“手势竞争场”机制来决议手势事件,最终确定接收触摸事件的控件。决议规则包括:

  • 手势识别器可以主动放弃竞争。
  • 剩余唯一识别器胜出。
  • Flutter UI录制

    为了实现手势事件的录制,我们需要在手势识别器回调上拦截事件。通过分析视图树(WidgetsFlutterBinding → RenderObject树),可以获取到所有参与手势处理的控件信息。以下是手势录制的核心实现:

    static GestureTapCallback onTapWithRecord(GestureTapCallback orgOnTap, BuildContext context) {    if (null != orgOnTap && null != context) {        final GestureTapCallback onTapWithRecord = () {            if (bStartRecord) {                saveTapInfo(context, TouchEventUIType.OnTap, null);            }            if (null != orgOnTap) {                orgOnTap();            }        };        return onTapWithRecord;    }    return orgOnTap;}static void saveTapInfo(BuildContext context, TouchEventUIType type, Offset point) {    if (null == point && null != pointerPacketList && pointerPacketList.isNotEmpty) {        final ui.PointerDataPacket last = pointerPacketList.last;        if (null != last && null != last.data && last.data.isNotEmpty) {            final ui.Rect rect = QueReplayTool.getWindowRect(context);            point = new Offset(                last.data.last.physicalX / ui.window.devicePixelRatio - rect.left,                last.data.last.physicalY /                    ui.window.devicePixelRatio - rect.top);        }    }    final RecordInfo record = createTapRecordInfo(context, type, point);    if (null != record) {        FlutterQuestionReplayPlugin.saveRecordDataToNative(record);    }    clearPointerPacketList();}

    Flutter UI回放

    手势回放分为两部分:

  • 匹配视图树:通过录制的信息匹配当前界面上的对应控件。
  • 模拟手势动作:在目标控件上生成原始触摸数据,确保触摸事件逼真可靠。
  • 滚动事件回放

    滚动事件回放需要考虑以下关键点:

  • 触摸点生成:确保触摸点数据的物理坐标和时间戳准确。
  • 滚动补偿:处理滚动过程中的距离和速度变化。
  • 事件发送:通过定时器循序发送触摸数据,直到达到目标位置。
  • 问题回放整体框架图

    整体框架图展示了Native与Flutter的协同工作流程,包括:

  • 数据捕获:通过系统底层接口获取UI事件流。
  • 信息存储:将手势事件信息存储到本地数据库。
  • 信息回放:根据录制信息在目标控件上复现手势事件。
  • 总结

    本文介绍了Flutter手势事件录制与回放的核心技术,包括手势原理、录制实现、回放逻辑及整体架构。通过这套解决方案,开发者可以快速定位用户反馈问题,提升问题复现效率,降低开发成本。

    后续优化方向包括:

  • 提升触摸事件模拟的逼真度(如滚动加速度)。
  • 解决录制与回放不一致性问题(如输入框回放不符)。
  • 如需了解更多技术细节,可以关注我们的公众号获取最新动态。如有建议或意见,欢迎在评论区留言。

    转载地址:http://svgb.baihongyu.com/

    你可能感兴趣的文章
    npm run build报Cannot find module错误的解决方法
    查看>>
    npm run build部署到云服务器中的Nginx(图文配置)
    查看>>
    npm run dev 和npm dev、npm run start和npm start、npm run serve和npm serve等的区别
    查看>>
    npm run dev 报错PS ‘vite‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
    查看>>
    npm scripts 使用指南
    查看>>
    npm should be run outside of the node repl, in your normal shell
    查看>>
    npm start运行了什么
    查看>>
    npm WARN deprecated core-js@2.6.12 core-js@<3.3 is no longer maintained and not recommended for usa
    查看>>
    npm 下载依赖慢的解决方案(亲测有效)
    查看>>
    npm 安装依赖过程中报错:Error: Can‘t find Python executable “python“, you can set the PYTHON env variable
    查看>>
    npm.taobao.org 淘宝 npm 镜像证书过期?这样解决!
    查看>>
    npm—小记
    查看>>
    npm上传自己的项目
    查看>>
    npm介绍以及常用命令
    查看>>
    NPM使用前设置和升级
    查看>>
    npm入门,这篇就够了
    查看>>
    npm切换到淘宝源
    查看>>
    npm切换源淘宝源的两种方法
    查看>>
    npm前端包管理工具简介---npm工作笔记001
    查看>>
    npm包管理深度探索:从基础到进阶全面教程!
    查看>>