写点什么

精细化曝光策略

  • 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:091349

评论

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

Split to Be Slim: 论文复现

华为云开发者联盟

人工智能 华为云 论文 华为云开发者联盟 企业号 4 月 PK 榜

Apache Flink ML 2.2.0 发布公告

Apache Flink

大数据 flink 实时计算

为什么说网络安全行业是IT行业最后的红利?

网络安全学海

网络安全 安全 信息安全 渗透测试 WEB安全

华为云GaussDB坚持技术引领,以数字化转型激活金融科技新动能

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 4 月 PK 榜

Go 语言快速入门指南:GET 和 POST 方法

宇宙之一粟

Go HTTP post GET 三周年连更

如何通过C#/VB.NET代码将PowerPoint转换为HTML

在下毛毛雨

html PowerPoint 文档转换

有道CEO周枫:当我们谈论大模型时,应该关注哪些新能力?

有道技术团队

手语识别:解锁语言交流的新时代

数据堂

世优科技AI数字人产品“世优BOTA”发布!全面提升AI虚拟员工能力

联营汇聚

FBEC大会 | 瑞云科技 CTO 赵志杰:元宇宙时代的基础设施——实时云渲染

3DCAT实时渲染

实时渲染 实时云渲染 实时渲染云

天呐!我真的没想到推特GIF动图保存到手机相册竟然简单几步就能完成!

frank

twitter

【FAQ】统一扫码服务常见问题及解答

HarmonyOS SDK

HMS Core

2023云数据库技术沙龙MySQL x ClickHouse专场成功举办

NineData

MySQL 腾讯云 阿里云 云数据库 技术沙龙

Rust、Go 和 Swift 在性能和并发性方面有何差异?

非凸科技

Go swift 性能 编程语言 高并发

没有主机跑开源软件?速来牧云助手免费领一台!

百川云开发者

云计算 开源 云主机 教程 免费

为开发者搭建创新舞台 OpenHarmony创新赛正式启动

最新动态

如何雇佣一名全民开发者?

草料二维码

开发者 低代码 无代码开发 无代码 无代码微信小程序

赋能开发者,开放原子全球开源峰会期待你的声音!

开放原子开源基金会

大数据 开源 开源软件

编程中最难的就是命名?这几招教你快速上手

阿里巴巴云原生

阿里云 编程 云原生

大语言模型时代狂飙以来,到底是谁在让你失业|社区征文

小诚信驿站

三周年征文

上海首个大模型产业发展研讨会圆满落幕,众顶尖专家共探大模型产业

NLP资深玩家

从零学习SDK(9)SDK的局限

MobTech袤博科技

DevOps 与研发效能资深技术专家张乐:研发效能的升维思考与降维执行

万事ONES

技术干货|如何利用 ChunJun 实现数据实时同步?

袋鼠云数栈

开源 数据采集

AI数字人产品“世优BOTA”发布会落幕,世优科技纪智辉演讲回顾

联营汇聚

常用工具

流火

文本搜索工具ack与grep

坚果

Linux 三周年连更

浅析低代码开发的典型应用构建场景

力软低代码开发平台

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