友盟页面统计 - 关于Viewpager中的Fragment的生命周期
生活随笔
收集整理的這篇文章主要介紹了
友盟页面统计 - 关于Viewpager中的Fragment的生命周期
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Activity和Fragment各自理論上的生命周期
- Activity的生命周期是較為經典也最清晰的,在此不表;
- Fragment從出現到廣泛運用也有一段時間了,其標準生命周期也僅比Activity多出一些流程,如onCreateView();
- Activity和Fragment在實際編碼中必定是結合出現的,表現為Activity作為容器,裝載有一個或若干個Fragment;
- 裝載多個Fragment時,經常使用TabHost和Viewpager作為載體;
- 在實際編碼中發現,Activity和Fragment的混合情況里,其生命周期的交叉可能與預想中有差別;
-
使用如下方式加載Fragment時:
[java] view plaincopy print?- 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()方法本身很接近我們的需求,它的局限點我采取了一個侵入式的解決方式:
[java] view plaincopy print?- 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?
轉載于:https://www.cnblogs.com/wangfeng520/p/5805926.html
總結
以上是生活随笔為你收集整理的友盟页面统计 - 关于Viewpager中的Fragment的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML5的viewport使用
- 下一篇: 木槿生活GODDESS香水多少钱一瓶阿。