博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Android Fragment】友盟统计 Fragment 页面显示隐藏的完美解决方案
阅读量:6225 次
发布时间:2019-06-21

本文共 3381 字,大约阅读时间需要 11 分钟。

在使用友盟统计的时候常常会遇到Activity加Fragment的组合,统计起来比较麻烦。

友盟给出的解决方案是在Activity的onResume()和onPause()方法中执行MobclickAgent.onResume()加MobclickAgent.onPause()统计时长然后在Fragment的onResume()和onPause()方法中执行MobclickAgent.onPageStart()加MobclickAgent.onPageEnd()统计页面

默认情况下在MobclickAgent.onResume()和MobclickAgent.onPause()方法中会自动执行MobclickAgent.onPageStart()和MobclickAgent.onPageEnd()来统计页面,要想不自动统计页面只需在Application或程序入口处执行MobclickAgent.openActivityDurationTrack(false)即可

这个方案在普通的使用方式中没啥问题,但在ViewPager中却有很严重的BUG。

众所周知ViewPager会在初始化的时候一次性初始化2个Fragment,并且这两个Fragment都处于resume状态。但用户只能看到第一个Fragment,这时候你能说第二个Fragment也显示了吗?我们只能说第二个Fragment也准备好了,不能说显示了。这样带来的BUG就是明明第二个Fragment用户都没有看到,却统计成了已显示。

那么还有没有合适的回调方法能够帮助我们准确的统计Fragment呢?当然有。

Fragment有个叫setUserVisibleHint(boolean)的方法就是专门设置显示不显示的,ViewPager会在初始化Fragment的时候以及切换Fragment的时候调用此方法设置是否显示。那是不是只重写这个方法然后调用MobclickAgent.onPageStart()加MobclickAgent.onPageEnd()就可以了,经过验证后只能很遗憾的告诉你,不可以!

因为ViewPager会在设置Adapter之后立即调用第一个、第二个fragment的setUserVisibleHint(boolean)方法设置为false,然后会对第一个fragment再次调用setUserVisibleHint(boolean)方法设置为true,然后才是onAttach()、onCreate(),很明显顺序不对。 另外当Fragment不是在ViewPager中使用的时候压根就不会调用setUserVisibleHint(boolean)方法

那么最终我们还是要结合Fragment的setUserVisibleHint(boolean)、onResume()、onPause()这三个方法才能完美的统计,最终实现方式如下所示:

public class MyFragment extends Fragment {    private String pageName;    public MyFragment() {        pageName = getClass().getSimpleName();    }    @Override    public void onResume() {        super.onResume();        if(getUserVisibleHint()){            onVisibilityChangedToUser(true, false);        }    }    @Override    public void onPause() {        super.onPause();        if(getUserVisibleHint()){            onVisibilityChangedToUser(false, false);        }    }    @Override    public void setUserVisibleHint(boolean isVisibleToUser) {        super.setUserVisibleHint(isVisibleToUser);        if(isResumed()){            onVisibilityChangedToUser(isVisibleToUser, true);        }    }    /**     * 当Fragment对用户的可见性发生了改变的时候就会回调此方法     * @param isVisibleToUser true:用户能看见当前Fragment;false:用户看不见当前Fragment     * @param isHappenedInSetUserVisibleHintMethod true:本次回调发生在setUserVisibleHintMethod方法里;false:发生在onResume或onPause方法里     */    public void onVisibilityChangedToUser(boolean isVisibleToUser, boolean isHappenedInSetUserVisibleHintMethod){        if(isVisibleToUser){            if(pageName != null){                MobclickAgent.onPageStart(pageName);                Log.i("UmengPageTrack", pageName + " - display - "+(isHappenedInSetUserVisibleHintMethod?"setUserVisibleHint":"onResume"));            }        }else{            if(pageName != null){                MobclickAgent.onPageEnd(pageName);                Log.w("UmengPageTrack", pageName + " - hidden - "+(isHappenedInSetUserVisibleHintMethod?"setUserVisibleHint":"onPause"));            }        }    }}```重点就是在setUserVisibleHint(boolean)中加上isResume()过滤,在onResume()和onPause()中加上getUserVisibleHint()过滤有同学该担心了,你上面不是说在普通使用方式中setUserVisibleHint(boolean)压根就不会被调用,那么意味着getUserVisibleHint()一直都是false,最终onResume()和onPause()中的代码根本就不会执行了,这样普通使用方式就不行了啊。我要告诉大家的是大家的是Fragment的源码中明确显示,getUserVisibleHint()方法返回的是mUserVisibleHint字段的值,而mUserVisibleHint字段默认值是true如果你需要ViewPager嵌套ViewPager,那么你还会遇到Fragment的mUserVisibleHint属性不同步的问题,请查看下一篇文章来解决下一篇:[【Android】解决ViewPager嵌套时Fragment的mUserVisibleHint属性不同步的问题](http://www.jianshu.com/p/e7449278e33d)复制代码

转载于:https://juejin.im/post/5cb41f7cf265da03775c445e

你可能感兴趣的文章
oracle错误-ORA-12519, TNS:no appropriate service handler found
查看>>
JavaScript的组成
查看>>
了解自己,了解他人
查看>>
古典密码-多表密码体制
查看>>
Python多进程(multiprocessing)
查看>>
本地hosts文件
查看>>
CF24D Broken robot
查看>>
apt --fix-broken install
查看>>
Linux 系统 Apache 301 重定向配置方法
查看>>
awk-sed
查看>>
创建、删除索引
查看>>
网络对抗技术_作业一_201521460018
查看>>
二维数组中的查找
查看>>
[CF983D]Arkady and Rectangles
查看>>
EXTJS4-----前言
查看>>
CSS 收集
查看>>
触发器
查看>>
Linux atop监控工具部署
查看>>
Mysql中一级缓存二级缓存区别
查看>>
字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
查看>>