【移動應(yīng)用開發(fā)技術(shù)】Android在多種設(shè)計下實現(xiàn)懶加載機制的方法_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Android在多種設(shè)計下實現(xiàn)懶加載機制的方法_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Android在多種設(shè)計下實現(xiàn)懶加載機制的方法_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Android在多種設(shè)計下實現(xiàn)懶加載機制的方法_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Android在多種設(shè)計下實現(xiàn)懶加載機制的方法_第5頁
免費預(yù)覽已結(jié)束,剩余2頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】Android在多種設(shè)計下實現(xiàn)懶加載機制的方法

前言前段時間在自己的練習(xí)項目中想用到懶加載機制,查看了大多數(shù)資料只介紹了在ViewPager+Fragment組合的情況下實現(xiàn)的懶加載,但是現(xiàn)在大多數(shù)App更多的是Fragmentmanager去管理主頁面多個Fragment的顯示與隱藏,然后主界面的某個或多個Fragment里又嵌套了多個Fragment+ViewPager(詳細見下圖),對于這種情況,適用于第一種的方式是不能直接解決第二種的情況的,所以寫下這篇文章,記錄一下踩的幾個坑,希望對同像我一樣的初學(xué)者提供一種思考方式作為參考(如果有錯誤或者不合適的地方,希望各位前輩能在評論區(qū)指出,非常感謝!)。關(guān)于懶加載1.什么是懶加載?懶加載也叫延遲加載,在APP中指的是每次只加載當(dāng)前頁面,是一種很好的優(yōu)化APP性能的一種方式。2.為什么要用懶加載?優(yōu)化APP性能,提升用戶體驗:如果用戶打開某頁面,就會去預(yù)加載其它的頁面時,數(shù)據(jù)集較小或者網(wǎng)絡(luò)性能較優(yōu)時還好,但是如果數(shù)據(jù)集過大或者網(wǎng)絡(luò)性能不佳時,就會造成用戶等待的時間較長,APP界面產(chǎn)生明顯的滯頓感的情況,嚴重影響到用戶的體驗。減少無效資源的加載,減少服務(wù)器的壓力,節(jié)省用戶流量:如果用戶只想瀏覽或者經(jīng)常瀏覽某個特定的頁面,如果使用預(yù)加載的方式,就會造成資源浪費,增加服務(wù)器的壓力等。

實現(xiàn)懶加載

1.ViewPager+Fragment情況

1.1遇到的問題在我們平時開發(fā)中,經(jīng)常使用ViewPager+Fragment的組合來實現(xiàn)左右滑動的頁面設(shè)計(如上圖),但是ViewPger有個預(yù)加載機制,默認會把ViewPager當(dāng)前位置的左右相鄰頁面預(yù)先初始化(俗稱預(yù)加載),即使設(shè)置setOffscreenPageLimit(0)也無效果,也會預(yù)加載。通過點進源碼中發(fā)現(xiàn),如果不主動設(shè)置setOffscreenPageLimit()方法,mOffscreenPageLimit默認值為1,即使設(shè)置了0(小于1)的值了,但是還會按照mOffscreenPageLimit=limit=1處理。1.2解決思路Fragment有一個非生命周期的setUserVisibleHint(booleanisVisibleToUser)回調(diào)方法,當(dāng)ViewPager嵌套Fragment時會起作用,如果切換ViewPager則該方法也會被調(diào)用,參數(shù)isVisibleToUser為true代表當(dāng)前Fragment對用戶可見,否則不可見。所以最簡單的思路:Fragment可見時才去加載數(shù)據(jù),不可見時就不讓它加載數(shù)據(jù)。據(jù)我們創(chuàng)建抽象BaseFragment,對其進行封裝。首先我們引入isVisibleToUser變量,負責(zé)保存當(dāng)前Fragment對用戶的可見狀態(tài)。同時還有幾個值得注意的地方:setUserVisibleHint(booleanisVisibleToUser)方法的回調(diào)時機并沒有與Fragment的生命周期有確切的關(guān)聯(lián),比如說,回調(diào)時機有可能在onCreateView()方法之后,也可能在onCreateView()方法之前。因此,必須引入一個標(biāo)志位isPrepareView判斷view是否創(chuàng)建完成,不然,很容易會造成空指針異常。我們初始化該變量為false,在onViewCreated()中,也就是view創(chuàng)建完成后,將其賦值為true。數(shù)據(jù)初始化只應(yīng)該加載一次,因此,引入第二個標(biāo)志位,isInitData,初始為false,在數(shù)據(jù)加載完成之后,將其賦值為true,下次返回此頁面時不會再自動加載。至此,我們的懶加載方法考慮了所有條件。也就是當(dāng)isVisibleToUser為true,isInitData為false,isPrepareView為true時,進行數(shù)據(jù)加載,并且加載后為了防止重復(fù)調(diào)用,將isInitData賦值為true。將懶加載數(shù)據(jù)提取成一個方法,那么這個方法該何時調(diào)用呢?首先setUserVisibleHint(booleanisVisibleToUser)方法中是必須調(diào)用的,即當(dāng)Fragment由可見變?yōu)椴豢梢姾筒豢梢娮優(yōu)榭梢姇r回調(diào)。其次,很容易忽略的一點。對于第一個Fragment,如果setUserVisibleHint(booleanisVisibleToUser)方法在onCreateView()之前調(diào)用的話,如果懶加載方法只在setUserVisibleHint(booleanisVisibleToUser)中調(diào)用,那么該Fragment將只能在被主動切換一次之后才能加載數(shù)據(jù),這肯定是不可能的,因此,我們需要在view創(chuàng)建完成之后,也進行一次調(diào)用。思來想去,在onActivityCreated()方法中是最合適的。我們在繼承的時候,在onViewCreated()方法中進行一些初始化就行了,這樣不會引起沖突。1.3BaseFragment代碼實現(xiàn)2.Fragment+ViewPager+Fragment情況

2.1遇到的問題如圖2,對于這種由Fragmentmanager管理主頁面的多個Fragment的顯示與隱藏,在其中的某個Fragment中又嵌套了多個Fragment的情況(如上圖),上面的方案是無法解決的,如果主頁面的Fragment直接繼承上面的BaseFragment,就會出現(xiàn)主頁的幾個Fragment都不會加載的現(xiàn)象,為什么會這樣呢,按道理說Fragment應(yīng)該可見了,加載數(shù)據(jù)的判斷邏輯應(yīng)該沒問題啊,而且上面那個demo也跑成功了。最終我發(fā)現(xiàn),問題出在setUserVisibleHint()這個方法上,點進去它的源碼發(fā)現(xiàn)注釋中有這么一句話:

Thismaybeusedbythesystemtoprioritizeoperationssuchasfragmentlifecycleupdatesorloaderorderingbehavior.

Thismaybeusedbythesystemtoprioritizeoperationssuchasfragmentlifecycleupdatesorloaderorderingbehavior.也就是說這個可能被用來在一組有序的Fragment里,例如Fragment生命周期的更新。告訴我們這個方法被調(diào)用希望在一個pager里,因此FragmentPagerAdapter所以可以使用這個,而主頁面的幾個Fragment我們是通過Fragmentmanager管理的,所以setUserVisibleHint()是不會被調(diào)用,而我們設(shè)置的isVisibleToUser=false默認值一直不會變,那么lazyInitData()方法也就一直不會執(zhí)行。2.2解決思路這里我的處理方式是,在lazyInitData()中多加了一段處理邏輯,如下:對于主頁面的多個Fragment只會在第二個判斷邏輯處理(因為它的isVisibleToUser值一直等于false),對于嵌套的Fragment只會經(jīng)過第一個處理邏輯(因為它的getParentFragment()!=null),然后通過onHiddenChanged()方法去加載lazyInitData()方法,這樣以來就能處理這種情況了。但是這時候又會出現(xiàn)一個問題,如果一個APP里第一種,第二種情況并存的話,這段代碼又不適合第一種情況了,因為對于第一種的情況當(dāng)判定isVisibleToUser為false時,雖然不走第一個處理邏輯,但是它的getParentFragment()一直是等于null的,那么它就會走第二個判斷邏輯,這樣又會預(yù)加載了。對于這種情況,我的處理方式:給每個Fragment設(shè)置一個標(biāo)志值,當(dāng)是第一種情況時,設(shè)為true,第二種情況時,設(shè)置false,然后再分別處理相應(yīng)的判斷邏輯。代碼如下:經(jīng)過這樣的處理之后,第一種情況和第二種情況,或兩者并存的情況下都能保證在繼承一個base下,實現(xiàn)懶加載。2.3BaseFragmentTwo最終代碼實現(xiàn)其它需要注意:①給viewpager設(shè)置adapter時,一定要傳入getChildFragmentManager(),否則getParentFragment()將會一直等于null,這會影響lazyInitData

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論