如何设计一个有效曝光的框架
本文发布于公众号:移动开发那些事如何设计一个有效曝光的框架
在前面的文章中,我们讲到了怎样去设计一个伪无埋点的框架,以及怎样低成本去解决该框架的关键的问题,还不了解伪埋点框架的同学建议先去看看之前的文章如何设计一个伪埋点框架。
在这篇文章里,我们将基于前面的无埋点框架来设计一个有效曝光的框架。整个文章将基于以下几点来组织:
- 相关概念介绍,如什么是有效曝光,为什么要设计有效曝光的框架;
- 有效曝光框架的组成,如曝光策略的设计,缓存的设计,可扩展性等;
1 概念介绍
1.1 什么是有效曝光
有效曝光:
有效曝光这一个词最开始是来源于广告领域(广告领域有按照曝光数来收广告费的计算模式:每千次曝光收到多少钱),一般的定义为:有效曝光指的是广告或内容被目标受众看到并产生一定影响的次数。它不仅仅是简单的展示次数,而是强调广告或内容对受众的实际影响。 。
与之相对应的是
常规曝光
广告或内容被用户看到了就算曝光,如手机浏览网页,一闪而过的热点新闻
我认为的有效曝光的极简定义为:用户看到了你的内容,并有一点点印象;
1.2 为什么要有有效曝光?
不管是常规曝光,还是有效曝光,其本质就是用来衡量广告或内容的效果:(如有100个从看到了广告,其中有2个人点进去看,那么其的曝光/点击率为:2%),最开始,许多广告主在投放广告时,会发现常规的曝光/点击率很差,转化效果很差,他们就去分析用户的数据,发现观看广告超过多少秒的用户的转化率就比较高,
进而推动行业去采用有效曝光来计算投放和转化的效果。
2 有效曝光的框架
基于前面的概念介绍的有效曝光的定义,我们把这个定义扩展到终端开发领域,则有效曝光的定义为:
View
可见的面积达到50%时算曝光(可见面积首次达到50%时算开始曝光);View
的曝光时长至少达到 2s(从开始曝光到结束曝光的时间超过2s);
这里的阈值 50% 和2s 只是一个经验值,实际的值可以根据业务的情况动态调整;
这里有效曝光的框架会围绕着以下几个部分来展开
- View 标识
- 数据存储
- 曝光计算
- 曝光缓存
- 曝光策略
- 框架的可扩展性
2.1 View标识
View
的标识主要用来判断当前View
是否需要做某些业务逻辑的处理,如是否需要进行曝光(后续也基于曝光来讨论)等。在决定怎样来标识这个View
前,我们先来了解一下Android
中的View
复用机制:
复用机制:(一般是通过列表控件实现,如ListView
,RecyclerView
)
一般只创建屏幕上可见的view
,而不是一次性创建所有数据项。当某个View
滚出屏幕时,将其放入一个缓存池中,等待后续需要时复用。
而且当刷新View
的数据时,即使数据没有更新,当前的View
也可能被重新创建。
这意味着我们在屏幕上看到的View
可能是前面已经曝光过的,也可能是没有曝光过的,那这里我们可以怎样来区分这些View
是否已经曝光过呢? 因为View
会存在复用(也可能重新被创建),所以不能单纯地用View
对象来判断标识这个View。因此需要设计一个机制来保证即不会漏掉曝光,也不会重复曝光,所以其实需要一个唯一id来标识当前的View
,这里我们通过一个UUID.randomUUID()
来生成一个View
的唯一ID,这个ID会一直伴随着View
。并在初始化时,通过setTag
的方式来与View
进行绑定。(这个ID只是内部用来判断逻辑的,真正的标识需要由业务设置,这样才不会由于复用机制引起问题)
2.2 数据存储
数据存储有两个作用:
- 一个存储当前正在显示的
View
列表,用于后续的业务逻辑的判断(如已经曝光,结束曝光等) - 另一个是存储当前已经上报过的曝光
View
的信息,用于做业务逻辑的过滤(如重新曝光等)
里主要利用前面的埋点框架里的自定义FrameLayout
里增加变量来存储
// 上一次曝光的View的信息
private Map<String, ExposureModel> lastVisibleViewMap = new ConcurrentHashMap<>();
这里的View
的信息并没有直接存储View
对象,而是存储其相关的信息,如
public class ExposureModel implements Cloneable {
public String viewID; //当前ViewID
public String id; // 业务设置的id;
public HashMap<String, Object> params;
public int timeThre; // 曝光时长阈值
public float areaThre; //曝光面积阈值
// 可以根据需求,增加其他的参数
}
2.3 曝光计算
由前面定义可知,有效曝光需要有条件同时满足:
- 曝光面积计算,当满足设定的阈值时,记录一个开始曝光时间;
- 曝光时长计算,在遍历时,判断当前的曝光时长;
2.3.1 曝光面积计算
这里主要是需要在当前View
的可见面积达到设定的阈值时,打一个开始曝光的时间,Android
中计算View
的可见面积时,
可通过getGlobalVisibleRect
来计算,简单的获取View
的可见面积比例为:
public static float getRealArea(View view) {
int width = view.getWidth();
int height = view.getHeight();
Rect GlobalVisibleRect = new Rect();
// 判断是否可见
boolean isVisibleRect = view.getGlobalVisibleRect(GlobalVisibleRect);
// 可见的情况下,计算可见的宽度和高度
if (isVisibleRect) {
int visibleWidth = GlobalVisibleRect.width();
int visibleHeight = GlobalVisibleRect.height();
// 可见面积 和实际面积的比值,得到一个曝光面积的值
return (visibleHeight * visibleWidth * 1.00F) / (width * height);
}
return 0.0F;
}
当判断View
的曝光面积达到设定的阈值时,会记录下当前View
的开始曝光的时间
2.3.2 曝光时长计算
曝光时长的计算这里比较简单,就是拿当前的时间 减去 开始曝光的时间,拿到一个已经曝光的时间A,用时间A和当前View设置的曝光时长对比,满足条件,则算当前View
产生一个有效曝光,此时就可调用上报SDK
的接口进行曝光上报和其他的业务处理了;
2.4 曝光缓存
曝光缓存主要解决是重复曝光 和View
复用引起的不会再次曝光问题,
比如:在ListView
中上下划动过程中,前面已经曝光过的view
就没上报曝光了(但有可能只是View
复用了,里面的数据其实是不一样的),或者某个已经曝光过的view
重新生成后,又重新生成一个曝光。这种情况下,缓存的判断就不能仅仅用前面的View
的标识来处理(View
会存在复用),这里我们需要增加一个复用的id,这个id需要能标识到对应的position
我们通过View
标识和复用id来缓存曝光(判断是否需要重新曝光)
2.5 框架可扩展性
现在我们的曝光框架其实都只是采用了一种的曝光策略:根据View
的曝光面积和曝光时长来计算曝光,假如业务想采用其他的曝光策略的话,这个框架能扩展吗?答案肯定是可以的,可以在存储View
相关的信息的数据model里,增加一个曝光策略的字段:
public class ExposureModel implements Cloneable {
// 其他的参数情况
int exposureStrategy; // 曝光策略,如 1 代表 有效曝光 ; 2 代表普通曝光 ;等
}
然后,在遍历里,根据给View
设置的曝光策略的值,来定义其是如何进行计算处理的;
3 总结
本文主要围绕:
- View 标识
- 数据存储
- 曝光计算
- 曝光缓存
- 曝光策略
- 框架的可扩展性
这几个点来说明如何设计一个有效曝光的框架,当然这里的描述是比较粗略的,真正实现时还需要考虑很多细节,想要交流更多的朋友可以留言
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具