写点什么

精细化曝光策略

  • 2019-09-23
  • 本文字数:2453 字

    阅读完需:约 8 分钟

目前贝壳找房 APP 端的曝光时机是写死的, 触发条件:卡片必须要完整展示在界面上; 在列表界面上下/左右滑动时单次/多次曝光同一个卡片。


现有方案的不足:


1.门限条件应改为 API 下发的;


2.缺少卡片在界面上显示的时长;


反例:


1.比如说列表有 1000 条记录,快速滑动列表到最后一条;用户并没有看清中间的 900 多条记录,这时要不要为这些记录做曝光埋点?


2.例如一个卡片高度为 100px,实际上只显示了 80px,是否要做一次曝光埋点。



当前问题:


如果只滑动这个程度,目前 app 不会为“附近地图”做曝光埋点,但该卡片的主要信息都已经展示了


行业对标:


今日头条、手机百度的曝光埋点策略做的很细, 比如卡片划入、划出时间,卡片显示多少比例可以算曝光等等。

解决方案

参考今日头条、手机百度的做法,实现类似的曝光策略。


1.为每种卡片设置不同的曝光策略;


2.APP 根据 API 下发的门限条件触发埋点;


3.记录卡片移入、移出屏幕的时间, 统计每个卡片真正显示的时长;


4.界面销毁、显示/隐藏是否触发曝光埋点。例如按 home 键时是否触发曝光埋点,再次进入是否触发埋点。 这些场景由 API 下发配置开关。



双向队列缓存当前 RecyclerView 显示的所有 ViewHolder, 用于执行卡片的曝光埋点函数。


在监听 RecyclerView 滑动事件时得到第一个可见位置、最后一个可见位置,根据参数判断是上滑或下滑,通过判断 ViewHolder 的 itemView top、bottom 参数值得出刚刚移入屏幕的卡片显示比例, 并根据 API 下发的门限值(最低显示比例)记录开始时间,在卡片即将划出屏幕时(API 下发的门限值)触发曝光埋点。 从而得出卡片的显示周期。


参考代码

滑动回调


public class CardExposureHelper extends RecyclerView.OnScrollListener { //缓存卡片的双向队列  private Deque<BaseHomeCard> deque;  //队列顶部Card的position  private int preFirstExposure;  //队列底部Card的position  private int preLastExposure;  /**   * 处理垂直方向卡片曝光   * @param manager   * @param isUp 是否向上滑动   */  private void onVerticalExposure(LinearLayoutManager manager,boolean isUp) {    int firstVisiblePosition = manager.findFirstVisibleItemPosition();    int lastVisiblePosition = manager.findLastVisibleItemPosition();    //根据曝光比例判断第一个可见卡片是否需要曝光    firstVisiblePosition = isVerticalExposure(firstVisiblePosition)?firstVisiblePosition:firstVisiblePosition+1;    //根据曝光比例判断最后一个可见卡片是否需要曝光    lastVisiblePosition = isVerticalExposure(lastVisiblePosition)?lastVisiblePosition:lastVisiblePosition-1;    //第一次曝光,曝光所有符合曝光比例的Card    if (preFirstExposure==0&&preLastExposure==0){      offerVerticalVisibleQueue(firstVisiblePosition,lastVisiblePosition,true);    }else if (isUp){      //向上滑动,把顶部不可见Card从顶部出队,底部进入可曝光的卡片入队      popVerticalVisibleQueue(preFirstExposure,firstVisiblePosition-1,true);      offerVerticalVisibleQueue(preLastExposure+1,lastVisiblePosition,false);    }else {      //对应向下滑动的策略      popVerticalVisibleQueue(lastVisiblePosition+1,preLastExposure,false);      offerVerticalVisibleQueue(firstVisiblePosition,preFirstExposure-1,true);    }    //更新队列的顶部position和底部position    preFirstExposure = firstVisiblePosition;    preLastExposure = lastVisiblePosition;  }    /**   * 入队操作   * @param start   * @param end   * @param isFirst 是否从顶部入队   */  private void offerVerticalVisibleQueue(int start,int end,boolean isFirst){    if (start>=0 && end<recyclerView.getAdapter().getItemCount() && start<=end){      if (isFirst){        for (int i=end;i>=start;i--){          onVerticalItemSlideInto(i,true);        }      }else {        for (int i=start;i<=end;i++){          onVerticalItemSlideInto(i,false);        }      }    }  }   /**   * 出队操作   * @param start   * @param end   * @param isFirst 是否从顶部出队   */  private void popVerticalVisibleQueue(int start,int end,boolean isFirst){    if (start>=0 && end<recyclerView.getAdapter().getItemCount() && start<=end){      if (isFirst){        for (int i=start;i<=end;i++){          onVerticalItemSlideOut(i,isFirst);        }      }else {        for (int i=end;i>=start;i--){          onVerticalItemSlideOut(i,isFirst);        }      }    }  }   /**   * 处理滑入(入队)可曝光的卡片   * @param position   * @param isFirst 是否从顶部滑入(入队)   */  private void onVerticalItemSlideInto(int position,boolean isFirst){    BaseHomeCard card = getBaseHomeCard(position);    if (isFirst){      deque.offerFirst(card);    }else {      deque.offerLast(card);    }    //回调卡片开始曝光事件    callItemExposure(card,position);  }    /**   * 处理滑出(出队)停止曝光的卡片   * @param position   * @param isFirst 是否从顶部滑出(出队)   */  private void onVerticalItemSlideOut(int position,boolean isFirst){    BaseHomeCard card;    if (isFirst){      card = deque.removeFirst();    }else {      card = deque.removeLast();    }    //回调卡片结束曝光事件    callItemEndExposure(card,position,isFirst);  }        
复制代码

展望

目前这是 APP 端做的技术储备, 如需上线仍需要产品经理做更细致的产品规划。


作者介绍:


高瑞 、贺宇成,Android 工程师,负责贝壳找房 app 安卓端研发工作。


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/TKgFlupncu-Fol-mH8OEYA


2019-09-23 10:091191

评论

发布
暂无评论
发现更多内容

10大流行软件测试工具

百度开发者中心

测试工具

又到一年“粽子节”,快来测测你包的粽子颜值几分

华为云开发者联盟

端午节 华为云 modelarts 粽子

从零开始学习3D可视化之场景层级(2)

ThingJS数字孪生引擎

大前端 可视化 数字孪生

C++内存访问错误检测

正向成长

内存泄露 内存溢出 Asan

Linux系统日常定位常用指令

正向成长

linux命令

极狐(GitLab)开课了!实践进阶五步走,助你成为DevOps专家

极狐GitLab

DevOps

WWDC21: Swift 5.5 新特性解读

阿里巴巴大淘宝技术

swift WWDC21

字节跳动Java岗6月9号一面经验分享

北游学Java

Java 字节跳动 面试

书山有路,学海无涯|靠谱点评

无量靠谱

股价预测的基本思路(1)

Qien Z.

6月日更 量化投资 股价预测

阿里大佬离职带出内网专属“高并发系统设计”学习笔记

Java架构师迁哥

亮相智源大会,字节跳动自研同传系统的技术实现

字节跳动技术团队

高并发场景创建JedisPool有哪些注意事项?

BUG侦探

并发 Jedis commons-pool

干货|一款实用iOS云真机的技术架构是如何搭建的?

ios

Webpack 简介

编程三昧

JavaScript 大前端 Node webpack 构建工具

公安合成作战指挥系统解决方案,警务实战指挥系统

【得物技术】浅尝UI自动化之Airtest实践

得物技术

自动化 测试 UI 自动化测试 测试落地

网络攻防学习笔记 Day41

穿过生命散发芬芳

网络攻防 6月日更

Vue3.0 组合式 API 分析与实践

百度开发者中心

开发者

动手实践,Linux安装php-vld全过程实录

架构精进之路

插件 6月日更 笔记分享

花了60天的时间肝出了这些spring,jvm,并发编程等学习笔记,春暖花开再战大厂!

Java架构师迁哥

Boss直聘转发超90W次,Java面试突击手册 火遍全网,却遭封杀

Java架构师迁哥

员工提出离职就消极怠工怎么办?

石云升

员工离职 职场经验 管理经验 6月日更

百分点数据科学实验室:烟草行业市场信息采集数据质量评估体系研究探索

百分点大数据团队

教学相长,物联网赋能教育数字化!

IoT云工坊

人工智能 物联网 智慧校园 智慧教室 智慧操场

【FlinkSQL】Flink SQL Query(三)- Join

Alex🐒

flink 翻译 FlinkSQL flink1.13

洞察 | 企业数字化转型费用高昂?低代码“骨折”给你!

优秀

低代码

百分点科技助力中国环境监测总站“生态环境质量会商平台”上线

百分点大数据团队

【案例】星环科技助力华夏基金大数据平台建设

星环科技

并发编程-AQS介绍和原理分析(上)

追风少年

并发编程 AQS

5分钟速读之Rust权威指南(二十一)闭包

wzx

rust

精细化曝光策略_文化 & 方法_高瑞 、贺宇成_InfoQ精选文章