页面统计(PV) 遇上 Fragment ,真的准吗?

版权声明:

本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。

未经允许,不得转载。

一、前言

相信每个上线的 App ,都有数据的统计需求,那么不可避免的会碰到页面统计,俗称: PV。

PV : ( Page View ) ,即页面浏览量或点击量,用户每次对这个页面的访问均被记录一次 PV。

那么本文就聊聊如何准确的统计到页面的 PV,其实如果是单个页面的 PV ,比较单纯一点会很好统计到,但是如果 ViewPager + Fragment 这种复杂组合的页面,对单个 Fragment 的 PV 进行统计,就需要一些其他的方法了。

首先明确一下我对 PV 的定义,这个页面,在用户场景下,展示一次,就算一次PV,那么涵盖几个点:

  1. 页面第一次展示。
  2. 页面进入其他页面又回来。
  3. 在当前页面退出到后台再切回来。
  4. 在当前页面锁屏后解锁再回来。

二、Activity 中直接使用 Fragment

有时候,为了方便移植,会以 Activity 内部嵌套一个 Fragment 的方式构成一个页面,其实这样结构的 PV ,非常的好统计到,只需要在其生命周期方法 onResume() 中,记录一下页面的统计点即可。这样就不会有遗漏,其实也没什么好说的。

三、ViewPager 内的 Fragment

到本文的主题了。

虽然一个Activity 嵌套 一个 Fragment 的场景是有的,但是有一些时候,我们会使用一个 ViewPager + Fragment 的组合结构,来承载更多的业务,实际上多个Fragment 的业务互不关联,对于关心数据的那帮人而言,它们应该算成独立的 PV。

1、遇到的问题

如果和前面的场景一样,在 Fragment.onResume() 中做页面统计,就会发现一个很尴尬的问题,这个统计,不会准确,有些 Fragment 的 PV 会多。

因为 ViewPager 的特性,决定了它实际上是会缓存前后两个Fragment 的,加上自身,最多的时候是会缓存三个,并且这个设定是无法修改的,我们没有办法将其修改只缓存当前的一个。

页面统计(PV) 遇上 Fragment ,真的准吗?_第1张图片
f-limt.png

可以看到,当设定的值小于 DEFAULT_OFFSCREEN_PAGES 的时候,就会又被设定为 DEFAULT_OFFSCREEN_PAGES ,这个值,就是 1 。

既然已经了解了这个特性,在使用 onResume() 来做统计,就会发生一个很尴尬的问题,第一个Fragment0 出现的时候,第二个 Fragment1 也会走生命周期方法 onCreate() → onResume() 。这样可能用户根本没有进入第二个 Fragment1 ,但是却被我们统计到了一次 PV。

所以这种情况下,使用 onResume() 来做 PV 的统计,是不靠谱的。

2、使用setUserVisibleHint

那么如果需要统计到 ViewPager 中 Fragment 的真实 PV 数据的话,就需要使用到 setUserVisibleHint() 这个方法了。

setUserVisibleHint() 方法在 v4包和 原生app 包中的 Fragment 都是有这个方法的,功能也是一样的,这里就 v4 包下的看看源码的说明。

页面统计(PV) 遇上 Fragment ,真的准吗?_第2张图片
f-fmethod.png

它会在这个 Fragment 被用户可见或者隐藏的时候调用,正好就符合我们对 Fragment 承载的页面 PV 统计的需要。

只需要重写该方法,并在 isVisibleToUser 为 true 的时候,记录一次该页面的 PV 。

但是这样,如果只是监听 setUserVisibleHint() 方法,还是会有遗漏,在此页面,如果切到后台再回来,或者锁屏再回来,都不会走到 setUserVisibleHint() 方法,所以还是需要配合 onResume() 来做 PV 的统计。

在 onResume() 的时候,通过 getUserVisibleHint() 拿到当前 Fragment 的显示状态,通过判断来决定是否需要打 PV 的统计点,这里就不细说了。

3、setUserVisibleHint 的原理

这样是不是皆大欢喜,你以为这样就完了吗?

那么这个方法在 Fragment 的生命周期方法中,并没有被提到,它是如何被调用的?为什么在 Activity 嵌套 Fragment 的场景下,不能使用它呢?

文档中其实已经说明了,它是一个声明周期之外的方法,它可能被用在一组 Fragment 里,如果对这一组 Fragment 的声明周期需要更新,可以自行调用 setUserVisibleHint() 方法。

那么,在我们这个场景下,setUserVisibleHint() 方法是在哪里被调用的呢?

这就需要追溯到 FragmentPagerAdapter 类里,在其中 instantiateItem() 和 setPrimaryItem() 方法,都有对其 Fragment 调用setUserVisibleHint() 方法,我们就 setPrimaryItem() 的源码看看它的实现。

页面统计(PV) 遇上 Fragment ,真的准吗?_第3张图片
f-primary.png

可以看到,它会在切换 item 的时候,如果当前 item 不为空,就调用 setUserVisibleHint(false) ,标记当前 Fragmet 被隐藏掉了。而将新的 item 调用 setUserVisibleHint(true),标记当前 Fragment 被显示了。

所以这里才是,ViewPager 内,Fragment.setUserVisibleHint() 方法会被调用的关键。

FragmentPagerAdapter 和 FragmentStatePagerAdapter 中,都有类似的实现,只要我们没闲的直接使用 PagerAdapter ,就不会有什么问题。

四、结语

看了源码,做到心里有底。统计的数据做不得马虎,一定要精准才能反应出真实的情况。

页面统计(PV) 遇上 Fragment ,真的准吗?_第4张图片
公众号二维码.jpg

你可能感兴趣的:(页面统计(PV) 遇上 Fragment ,真的准吗?)