友盟页面统计 - 关于Viewpager中的Fragment的生命周期

Activity和Fragment各自理论上的生命周期

  • Activity的生命周期是较为经典也最清晰的。在此不表;
  • Fragment从出现到广泛运用也有一段时间了。其标准生命周期也仅比Activity多出一些流程,如onCreateView();

  • Activity和Fragment在实际编码中必然是结合出现的,表现为Activity作为容器,装载有一个或若干个Fragment;
  • 装载多个Fragment时,常常使用TabHost和Viewpager作为载体;
  • 在实际编码中发现,Activity和Fragment的混合情况里。其生命周期的交叉可能与预想中有区别;

  • 使用例如以下方式载入Fragment时:

    getSupportFragmentManager()
          .beginTransaction()
          .add(R.id.fragment_container, mFragment, SHARE_PUBLIC_LIST_FRAGMENT_TAG)
          .commitAllowingStateLoss();

    其onResume和onPause运行过程为:

    • Activity - onResume
    • Fragment - onResume
    • Activity - onPause
    • Fragment - onPause

友盟-页面统计要求

  • Activity和Fragment共同体页面统计中。须要保证线性不交叉,每一个onPageStart都有一个onPageEnd配对,
  • 如:onPageStart ->onPageEnd-> onPageStart -> onPageEnd -> onPageStart ->onPageEnd
  • 这样才干保证每一个页面统计的正确。

Viewpager中Fragment的生命周期

  • ViewPager装载Fragment一般使用FragmentPagerAdapter或FragmentStatePagerAdapter,相同借助FragmentManager,在adapter的getItem方法中依据position制定显示的fragment
  • 因为Viewpager的缓存特点,Viewpager启动时其第一个Fragment页面及待缓存的页面都将按顺序呢開始他们的正常生命周期,走向onResume。即:
    • Viewpager所在Activity - onResume
    • Fragment1 - onResume
    • Fragment2 - onResume
    • Fragment3 - onResume
  • 因为这若干个页面的生命周期被同一时候催化了。影响了我们的单一推断,即无法推断“真正”显示和消失在使用者眼前的页面。

解决方式

  • 方案1:设置Viewpager的缓存机制,不缓存除当前页以外的页面数据,所见即所得,离开即销毁;
  • 此方案对需求修改较大,且较影响用户体验;

  • 方案2:重载Fragment.onHiddenChanged(boolean hidden)方法,其參数hidden代表当前fragment显隐状态改变时。是否为隐藏状态,可通过check此參数作处理;
  • 此方案局限在于本方法的系统调用时间发生在显隐状态改变时,但第一次显示时此方法并不调用;

  • 方案3:重载Fragment.setUserVisibleHint(boolean isVisibleToUser)方法。其參数isVisibleToUser顾名思义最接近我们的需求,代表页面是否“真正”对使用者显示;
  • 此方案局限在于此方法的第一次系统调用甚至早于Fragment的onCreate方法,故其第一次调用时isVisibleToUser值总为false,影响我们对生命周期顺序的判定;
    • Fragment1 - isVisibleToUser - false (多余)
    • Fragment1 - isVisibleToUser - true
    • Fragment1 - isVisibleToUser - false
    • Fragment2 - isVisibleToUser - false (多余)
    • Fragment2 - isVisibleToUser - true
    • Fragment2 - isVisibleToUser - false

实际採用的解决方式

  • 依据对产品需求的理解和用户体验的统一,选择在方案3基础上加以改进;
  • setUserVisibleHint()方法本身非常接近我们的需求,它的局限点我採取了一个侵入式的解决方案:
      protected boolean isCreated = false;
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          // ...
          isCreated = true;
      }
    
      /**
       * 此方法眼下仅适用于标示ViewPager中的Fragment是否真实可见
       * For 友盟统计的页面线性不交叉统计需求
       */
      @Override
      public void setUserVisibleHint(boolean isVisibleToUser) {
          super.setUserVisibleHint(isVisibleToUser);
    
          if (!isCreated) {
              return;
          }
    
          if (isVisibleToUser) {
              umengPageStart();
          }else {
              umengPageEnd();
          }
    
      }
  • 对onCreate方法结束的一个标记就可以解决这个问题。

  • 切记:此标记的改变请勿放在Fragment的onActivtyCreate方法中。此方法调用滞后于setUserVisibleHint的推断

One more thing

  • Viewpager装载Fragment时还有还有一个坑,Viewpager的父容器(Activity或Fragment)在显隐状态改变时。如在Activity的onResume和onPause调用时,并不会主动通知Viewpager内的Fragment运行其应用的生命周期,故我们须要再添加手动强制调用两次
  • 在Activity中查询到当前的Fragment,并运行其内方法。须要借助Viewpager。并改写其PagerAdapter;
  • 我採用了此文提到的Second Solution:怎样获得ViewPager当前显示的Fragment?
时间: 2024-10-06 00:40:02

友盟页面统计 - 关于Viewpager中的Fragment的生命周期的相关文章

在Viewpager中的Fragment使用ContextMenu问题

ContextMenu用法 上下文菜单ContextMenu由系统支持,常用于通过长按控件弹出列表形菜单,实现步骤如下 onCreateContextMenu方法 创建菜单 registerForContextMenu方法,为需响应的控件注册 onContextItemSelected方法,响应点击 在Viewpager中的Fragment使用ContextMenu发生的问题 在我的具体项目环境中,Viewpager中存在3个Fragment(0/1/2),并继承自一个父类BaseFragmen

友盟Umeng统计、自定义统计使用

友盟统计分析是移动终端上不可多得的佳品,鉴于在开发中使用到,随笔写下使用过程. 友盟SDK下载(包含统计功能和自动更新功能): 第一步:导入SDK 1. 解压文件,libs 文件夹内的jar文件直接复制到eclipse工程同名文件夹内:然后点击build Path 2. 将 res 内所有文件复制到eclipse工程内,合并res资源,所有资源前缀均为 umeng_ . 第二步:添加权限及相关信息 1. 使用统计功能添加如下权限: <uses-permission android:name=&quo

iOS之友盟错误统计解决

http://www.cocoachina.com/ios/20150720/12627.html First 相信有很多开发者在项目中加入了友盟统计,其中一个最主要的功能就是查看线上版本统计到的错误.但是当你看到这样的信息时: 会不会有这样的想法: 这尼玛到底是什么鬼?!! 此时你可能会百度(干得漂亮!),我相信你“闪闪”的双眼肯定会看到这篇文章的:dSYM文件分析工具.具体用法我就不重复了,博主写的很详细,而且这个工具真的真的很好用! Second 但是,友盟还统计到了这么一堆错误: 这尼玛

防止ViewPager中的Fragment被销毁

pager.setOffscreenPageLimit(2); 就可以让ViewPager多缓存一个页面 防止ViewPager中的Fragment被销毁,布布扣,bubuko.com

viewpager中fragment的生命周期管理

viewpager中fragment的生命周期管理 - i_bobby - 开源中国社区 调试fragment的时候发现一个莫名其妙的事情,viewpager中包含4个fragment,其中第一个和第三个fragment是要联网取得数据的,如图: 界面刚进去的时候显示第一个fragment,通过log信息,我发现two fragment竟然"偷偷"走了一遍的生命周期!着实把我震惊了! 然后我滑动到two,发现第三个也"偷"了一遍生命周期,也就是说,手机在显示第二个不

【转】WPF中的窗口的生命周期

原文地址:http://www.cnblogs.com/Jennifer/articles/1997763.html WPF中的窗口的生命周期 WPF中所有窗口的基类型都是System.Windows.Window.Window通常用于SDI窗口和对话框.Window在应用程序中除了一个设计用于托管顶级内容的控件外,就别无他物了.典型的,可以混合使用标记和代码来定义一个窗口.代码如下: 在xaml页: <Window x:Class="WPFApplication1.MainWindow&

struts2.0中Action的对象生命周期详解!!(转)

原文出处:http://blog.csdn.net/wxy_g/article/details/2071662 有很多人问Struts2.0中的对象既然都是线程安全的,都不是单例模式,那么它究竟何时创建,何时销毁呢? 这个和struts2.0中的配置有关,我们来看struts.properties ### if specified, the default object factory can be overridden here ### Note: short-hand notation is

hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)

三态的基本概念: 1,  暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象: 2,  持久化状态(Persistent):与session关联而且在数据库中有对应数据.已经持久化,添?到了Session缓存中.如通过hibernate语句保存的对象.处于此状态的对象叫持久对象: 3,  游离状态(Detached):持久化对象脱离了Session的对象.如Session缓

Java中的线程的生命周期大体可分为5种状态

Java中的线程的生命周期大体可分为5种状态. ①NEW:这种情况指的是,通过New关键字创建了Thread类(或其子类)的对象 ②RUNNABLE:这种情况指的是Thread类的对象调用了start()方法,这时的线程就等待时间片轮转到自己这,以便获得CPU:第二种情况是线程在处于RUNNABLE状态时并没有运行完自己的run方法,时间片用完之后回到RUNNABLE状态:还有种情况就是处于BLOCKED状态的线程结束了当前的BLOCKED状态之后重新回到RUNNABLE状态. ③RUNNING