1. 程式人生 > >效能優化系列之fragment的懶載入

效能優化系列之fragment的懶載入

     自從實習以來一直在忙著趕專案進度,沒有時間(懶)總結。現在終於有空總結一下這兩個多月的收穫了。從效能優化中的fragment懶載入開始梳理吧。      專案中使用ViewPager+Fragment,拿練手專案xMusic來說吧,在MainActivity中有兩個fragment,一個是本地播放頁面,一個是“發現”頁面,“發現”頁面包含廣告輪播圖和推薦歌單,圖片資源比較多。正常開啟app時兩個fragment都會進行網路請求載入資源。剛開啟app的時候,記憶體佔用能上到88-90m。對於很大一部分只聽本地歌曲的使用者來說,載入“發現”頁面不僅佔用記憶體,還消耗網路資源。      ViewPager中有一個方法  setOffscreenPageLimit(int limit)  可以設定預載入的頁面數量。通過原始碼我們可以知道,這個方法設定的limit最終都不會小於1。因此對於我們這種情況,setOffscreenPageLimit(int limit)是無效的。 public void setOffscreenPageLimit(int limit) {     if (limit < DEFAULT_OFFSCREEN_PAGES) {         Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "                 + DEFAULT_OFFSCREEN_PAGES);         limit = DEFAULT_OFFSCREEN_PAGES;     }     if (limit != mOffscreenPageLimit) {         mOffscreenPageLimit = limit;         populate();     } }      這時候就需要使用fragment的懶載入機制,在使用者手動滑入“發現”頁面時fragment才進行載入,節省資源。      fragment中提供一個方法 setUserVisibleHint,這個方法會在fragment對使用者可見/不可見時回撥,但是它並不在fragment的生命週期中,因此無法保證和生命週期方法的呼叫順序。      建立一個抽象類BaseLazyFragment,然後定義幾個標識位 private boolean isFirstVisible = true; private boolean isFirstInvisible = true; private boolean isViewCreated; private boolean isUIVisible;      重寫方法onViewCreated,並在其中進行載入操作(最終是否載入還取決於當前fragment是否可見,這將在lazyLoad中進行判斷): @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {     super.onViewCreated(view, savedInstanceState);     isViewCreated = true;     lazyLoad(); // 執行懶載入,因為無法確定setUserVisibleHint和onViewCreated哪個方法先執行,因此兩個方法裡面都需要呼叫lazyLoad }      然後重寫方法: @Override public void setUserVisibleHint(boolean isVisibleToUser) {     super.setUserVisibleHint(isVisibleToUser);     if (isVisibleToUser) {         isUIVisible = true; //當前fragment可見         if (isFirstVisible) {             //如果是第一次可見,則進行懶載入             isFirstVisible = false;             lazyLoad();         } else {             //不是第一次可見,則呼叫onUserVisible()             onUserVisible();         }     } else {         isUIVisible = false;         if (isFirstInvisible) {             isFirstInvisible = false;             //第一次不可見             onFirstUserInvisible();         } else {             //非第一次不可見             onUserInvisible();         }     } }      新增lazyLoad方法,執行懶載入: private void lazyLoad() {     if (isViewCreated && isUIVisible) { //需要進行雙重判斷,避免因為setUserVisibleHint先於onViewCreaetd呼叫時,出現空指標         onFirstUserVisible();  //進行初次可見時的載入     } }      新增幾個抽象方法: protected abstract void onFirstUserVisible(); protected abstract void onUserVisible(); protected abstract void onFirstUserInvisible(); protected abstract void onUserInvisible();

     Fragment的懶載入大概就是這樣,比較簡單。新增幾個標識位判斷是否是第一次可見/不可見、onViewCreated是否執行完(必要,否則setUserVisibleHint在onViewCreated執行完前回調,然後進行懶載入的話可能會導致空指標)。在加入懶載入之後,開啟app時的記憶體佔用能降到70m左右,下降了近20%,對於一些效能較差的使用者還是比較關鍵的。

    不過懶載入也有壞處就是使用者第一次進入頁面時需要短暫等待載入。因此是否需要懶載入得根據產品定位、目標人群等來決定,這就是產品經理需要考慮的問題了蛤蛤。 完整的BaseLazyFragment程式碼如下: import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public abstract class BaseLazyFragment extends Fragment {     private boolean isFirstVisible = true;     private boolean isFirstInvisible = true;     private boolean isViewCreated;     private boolean isUIVisible;     @Nullable     @Override     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {         Log.i("LazyLoad", getClass().getName() + "onCreateView");         if (getLayoutId() != 0) {             return inflater.inflate(getLayoutId(), container, false);         } else {             return super.onCreateView(inflater, container, savedInstanceState);         }     }     @Override     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {         super.onViewCreated(view, savedInstanceState);         isViewCreated = true;         lazyLoad(); // 執行懶載入,因為無法確定setUserVisibleHint和onViewCreated哪個方法先執行,因此兩個方法裡面都需要呼叫lazyLoad     }     @Override     public void setUserVisibleHint(boolean isVisibleToUser) {         super.setUserVisibleHint(isVisibleToUser);         if (isVisibleToUser) {             isUIVisible = true; //當前fragment可見             if (isFirstVisible) {                 //如果是第一次可見,則進行懶載入                 isFirstVisible = false;                 lazyLoad();             } else {                 //不是第一次可見,則呼叫onUserVisible()                 onUserVisible();             }         } else {             isUIVisible = false;             if (isFirstInvisible) {                 isFirstInvisible = false;                 //第一次不可見                 onFirstUserInvisible();             } else {                 //非第一次不可見                 onUserInvisible();             }         }     }     private void lazyLoad() {         if (isViewCreated && isUIVisible) { //需要進行雙重判斷,避免因為setUserVisibleHint先於onViewCreaetd呼叫時,出現空指標             initViewsAndEvents();             onFirstUserVisible();  //進行初次可見時的載入         }     }     protected abstract int getLayoutId();     protected abstract void initViewsAndEvents();     protected abstract void onFirstUserVisible();     protected abstract void onUserVisible();     protected abstract void onFirstUserInvisible();     protected abstract void onUserInvisible(); }

相關推薦

效能優化系列fragment載入

     自從實習以來一直在忙著趕專案進度,沒有時間(懶)總結。現在終於有空總結一下這兩個多月的收穫了。從效能優化中的fragment懶載入開始梳理吧。      專案中使用ViewPager+Fragment,拿練手專案xMusic來說吧,在MainActivity中有兩

提交訂單效能優化系列002-引入自己編寫的資料庫連線池

資料庫連線池對效能的影響 總是在各種地方看到類似的說明:“資料庫連線池是非常昂貴的資源。” 那麼請問“非常昂貴”到底是有多昂貴呢? 在我的機器上的測試結果是:從資料庫獲取一個連線的平均耗時大

提交訂單效能優化系列003-測試阿里巴巴的druid資料來源

概括總結 使用druid資料來源之後,相對於第002版自己隨手寫的資料庫,效能反而下降了8.49%。原因在於,002版是“隨手”寫的,因此功能非常簡陋,要什麼沒什麼,只能從記憶體中獲取連線,因此很快。

提交訂單效能優化系列004-測試hikari資料來源

概括總結 使用hikari資料來源之後,相對於第003版的druid資料來源,從提交訂單這個複雜的操作上來說,效能提升了17.79%。而從獲取資料庫連線這一簡單的操作上來說,hikari比druid優秀幾百倍。 004版本更新說明 pom.xml檔案中

提交訂單效能優化系列006-普通的Thread多執行緒改為Java8的parallelStream併發流

概括總結 Java8的parallelStream併發流能達到跟多執行緒類似的效果,但它也不是什麼善茬,為了得到跟上一版本的多執行緒類似的效果,一改再改,雖然最後改出來了,但是還是存在理解不了的地方。

提交訂單效能優化系列009-對比整個方法同步與方法中的部分程式碼同步

概括總結 在用到synchronized關鍵字的時候,憑直覺就會加在方法上,比如public static synchronized void test(){},但是這種直覺不見得是對的,估計大部分時候是出圖方便,想偷懶,才直接加到方法上的。推薦的做法是:僅僅

提交訂單效能優化系列011-放棄java同步,引入資料庫修改行數來驗證庫存

概括總結 既然Java同步之後,效能這麼差,那麼有沒有辦法可以不使用Java同步呢?有的,那就是利用資料庫修改的行數來驗證庫存。另外,假設現在庫存是10,需要減少1,推薦的做法是update Goods set stock=stock-1,而不是update

提交訂單效能優化系列012-引入FutureTask

概括總結 引入FutureTask能提高併發度,相應就可以提升效能,這次測試的結是,提升了38.93%(參考值)。它的缺點也很明顯,就是增加了程式碼的複雜度,不方便閱讀了,且對異常也要額外處理,而且大

提交訂單效能優化系列013-測試SQL語句中少查詢幾個欄位(包括大欄位)

概括總結 這一版本寫了兩個測試類,一個測試類中查詢全部欄位,另一個測試類中只查詢必要的欄位,然後對比效能。結論是:根據是減少的欄位的長度不同,效能會不同。具體請檢視下面的測試結果。 013版本更新說

提交訂單效能優化系列015-收貨地址由根據ID查詢改為傳參

概括總結 在電商下單時,一般都需要選擇收貨地址。這時候,在頁面顯示的資訊已經包含手機號、姓名、詳細地址、地址ID等資訊了。那麼這時候可以有兩種選擇,1、只把地址ID作為引數傳過去,後臺根據ID重新查詢

提交訂單效能優化系列016-快取商品

概括總結 這一版測試把商品資訊存在記憶體中,而不是每次都查詢資料庫。結果是:查詢快取比查詢資料庫的效能好5.28%。 016版本更新說明 測試結果 統計10次測試的平均值之後: Versio

提交訂單效能優化系列017-資料庫ID為int(10)型別與long(20)型別的對比

概括總結 int(10)型別的效能比long(20)型別的效能好4.01%(差別不明顯)。 017版本更新說明 這一版本有兩個SQL檔案: 另外一個比較重要的改動是,之前的版本是測試10次,然後

JPA] 效能優化: 4種觸發載入的方式

在一個JPA應用中,可以通過懶載入來提高應用的效能。這一點毋庸置疑,但是懶載入不等於不載入,在某個時刻還是需要載入這些資料的,那麼如何觸發這個載入的行為才能夠事半功倍呢? 這裡我想說一點題外話,面試的時候我也會考察被面試者對於JPA/Hibernate的看法,

AndroidFragment載入

還記得以前使用ViewPager+Fragment時根本不考慮效率問題,一股腦的多頁資料載入導致卡死,還自我安慰說我設定了setOffscreenPageLimit了啊,而實際上跟蹤原始碼我們發現DEFAULT_OFFSCREEN_PAGES = 1,所以即便s

Android效能優化系列記憶體優化

在Java中,記憶體的分配是由程式完成的,而記憶體的釋放是由垃圾收集器(Garbage Collection,GC)完成的,程式設計師不需要通過呼叫函式來釋放記憶體,但也隨之帶來了記憶體洩漏的可能,上篇部落格,我介紹了 Android效能優化系列之佈局優化,本篇部落格,我將介

Android效能優化系列佈局優化

在Android開發中,UI佈局可以說是每個App使用頻率很高的,隨著UI越來越多,佈局的重複性、複雜度也會隨之增長,這樣使得UI佈局的優化,顯得至關重要,UI佈局不慎,就會引起過度繪製,從而造成UI卡頓的情況,本篇部落格,我就來總結一下UI佈局優化的相關技巧。

Android效能優化系列Bitmap圖片優化

在Android開發過程中,Bitmap往往會給開發者帶來一些困擾,因為對Bitmap操作不慎,就容易造成OOM(Java.lang.OutofMemoryError - 記憶體溢位),本篇部落格,我們將一起探討Bitmap的效能優化。 為什麼Bitmap

Android優化方案--Fragment載入實現

一、背景 在Android應用中,ViewPager是我們不可避免使用的一個控制元件,因為它可以使我們在佔用較少空間的同時,增強內容的豐富性,同時以其內部流淌著Google的血液,所以它幾乎成了每一個App的標配控制元件。但是,假如ViewPager的每一個F

【java】itoo項目實戰hibernate 載入優化性能

bsp xtra extra pda 程序 前端框架 外連接 獲取 轉換成 在做itoo 3.0 的時候,考評系統想要上線,就開始導入數據了,僅僅導入學生2萬條數據,可是導入的速度特別的慢。這個慢的原因是由於導入的時候進行了過多的IO操作。可是導入成功之後,

[Android 效能優化系列]佈局篇減少你的介面層級

轉載請標明出處(http://blog.csdn.net/kifile),再次感謝 在接下來的一段時間裡,我會每天翻譯一部分關於效能提升的Android官方文件給大家 效能優化之佈局篇: 題外話: 複雜的佈局,既會提高我們的設計難度,也會降低我們的程式碼效