开发必读:网易专家解读Android ABTest 框架设计

作者 : 开心源码 本文共2240个字,预计阅读时间需要6分钟 发布时间: 2022-05-12 共292人阅读

应用中不同的场景、设计方案,不经过测试,你永远不知道消费者会更偏好哪一种。面对随时可能变更的产品需求,开发人员如何才能在保证测试进程的同时,让工作也变得高效、省力?

本章内容,网易严选Android资深开发张云龙为您解读《Android ABTest 的框架设计》

概述

什么是Android ABTest ?

AB测试是为web或者app制作两个(A/B)或者多个(A/B/n)版本,在同一时间维度,分别让组成成分相同或者类似的访客群组随机访问这些版本,收集各群组的客户体验数据和业务数据,最后分析评估出最好版本正式采用。
在网易严选中,张云龙团队涉及的业务内容基本分为两类:

1、纯业务逻辑的测试。如:分享给微信好友、分享微信小程序、分享网页。

但因为我们无法预判不同的业务场景对客户拉新的助力效果如何,所以这种情况下,会进行AB测试。

2、UI变化。下图体现的就是一个UI的改变,“立即购买”和“加入购物车”的位置发生变化,当然属性也有变化,背景颜色也有替换。

1.png

本章内容将围绕四部分开展:

  • A/B/n设计与实现
  • ViewID实现与优化
  • UI属性动态修改
  • UI重排版与替换

A/B/n设计与实现

2.png

以上是一段常见的业务逻辑测试方案代码,从这个方案中可以发现存在以下问题:

  • 业务上层开发的同学需要关心协议数据内容;
  • if/else方案出现重复代码,当产品上线后,测试版本发生变化时,会出现一个协议多处代码随时变化的情况,处理起来费时费力;
  • 另外也容易出现历史老版本两端体现不一致问题。
  • 因而,做A/B/n的设计与实现时,要注意以下方面:设计协议对接层规避 if/else
  • A/B/n 实例管理
  • 后端数据同步
  • 多种生效策略

下图是我写的ABTest的实例,这是协议对接层的代码,通过注解的方式,指定itemID。

3.png

在ABTest的升级逻辑中,涉及了立即升级、热启动升级、冷启动升级。

当数据处于立即升级策略时,会自动调用基类接口 onUpdateConfig,协议对接层的同学只要要通过这个接口即可以实现需求,并可以通过注解来指定不同caseld下的初始化方法。通过指定 defaultInit 注解,后端的AB协议即便撤销,业务层的执行逻辑也能明确。

这种通过协议对接层隔离业务上层和协议数据的做法,能保证在协议数据发生变化的时候,业务上层代码并不需要改动,避免了业务上层逻辑的频繁多处修改,以提高效率。

4.png

ViewID实现与优化

ViewID的实现有两点准则:

  • 唯一性,是指同一界面中,各个控件的ID是唯一的、不同的
  • 一致性,是指屡次进入同一个界面,控件 ID 是相同的、不变的。
    初步有以下方案:
    1、View.getId()。该方案可以排除,由于大部分控件的 ID 是不会指定的,布局文件中指定了屡次编译也会发生变化;
    2、XPath,根据场景树计算。大部分可视化埋点方案或者无埋点方案都是用这种方法去做的,mixpanel、百分点、网易乐得和网易 HubbleData 使用的就是这种方案。
    XPath优点和缺点都非常显著:
  • 优点是XPath对于业务层开发是完全无侵入的,无论是用xml生成布局还是通过动态生成,都可以计算XPath值;
  • XPath缺点是在多版本开发过程中,假如布局发生变化,同一个控件的XPath值就会发生变化,无法保证跨版本的 ViewID 一致性,会对后端的数据分析产生麻烦。
    3、得到 Android 提出的 TouchTarget 方案,针对 XPath 的缺点做了改进:在客户点击时,可以根据当前的 Activity 名字加上控件所在布局的资源名、ID资源名,拼凑起来得到它的 ViewID。
    但这种方案会对业务开发产生入侵。
    考虑到 ABTest 的场景中,很可能不需要跨多版本收集数据分析,我们采用 XPath 的方案。

UI属性动态修改

如何动态地修改线上UI属性?

总结下来有以下几点:

  • 利用 ViewID 定位控件;
  • 修订数据协议,修改控件,修改属性;
  • 把握作用时机。要保证在用户看到页面之前就修改完成;
  • 可视化方式,生成数据和效果检查
  • 自己设置控件和属性。SDK 可以预置大部分常见属性;而自己设置属性,可以让业务层开发制定,包含两方面:属性的设置、可视化编辑器添加编辑项。

    5.png
    6.png

UI 重排版与替换

7.jpg

可以从上图看到,A和B之间的修改并不只是属性修改,布局也在发生变化。这其中涉及了两点:

  • 定位控件,原布局阻断,新布局算法应用;
  • 重布局后需要属性设置继续生效,所以ViewID不能变化。

相似上述这种场景,假设有三个子控件,重新布局该如何做?

实现其实非常简单,我们只要要在中间加入StubCSSLayout(SDK 内置布局控件),插进去即可以起到承上启下的作用(承上:阻隔原布局算法,启下:应用新布局算法)。

8.png

想要 ViewID 在重布局前后不变,只要在计算 XPath 的过程中,将 StubCSSLayout 忽略掉,就能保证这一点。
在实际操作中,也可能遇到特殊需求,这就要求创立新的布局。
ndroid 开发中,常用的 setContentView(@LayoutRes int layoutResID) 方式创立布局有如下几点关键步骤:

  • 根据ID得到文件路径,进行布局;
  • 根据路径,获取long类型的xmlBlock;
  • 构建Java类XmlBlock;
    清楚了原生流程,通过利用 XmlBlock(byte[] data) 构造函数,构建 XmlBlock 对象来实现布局下发和创立的功能。
    [图片上传失败…(image-eb243b-1553571100064)]

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 开发必读:网易专家解读Android ABTest 框架设计

发表回复