RecyclerView 性能優化 | 安卓 offer 收割基

阿里四面有三面都問了這個問題,在此作了整理,但願能夠幫助到你們,歡迎查漏補缺。java

數據處理和視圖加載分離

咱們知道,從遠端拉取數據確定是要放在異步的,在咱們拉取下來數據以後可能就匆匆把數據丟給了 VH 處理,其實,數據的處理邏輯咱們也應該放在異步處理,這樣 Adapter 在 notify change 後,ViewHolder 就能夠簡單無壓力地作數據與視圖的綁定邏輯,好比:android

mTextView.setText(Html.fromHtml(data).toString());
複製代碼

這裏的 Html.fromHtml(data) 方法可能就是比較耗時的,存在多個 TextView 的話耗時會更爲嚴重,這樣便會引起掉幀、卡頓,而若是把這一步與網絡異步線程放在一塊兒,站在用戶角度,最多就是網絡刷新時間稍長一點。git

數據優化

分頁拉取遠端數據,對拉取下來的遠端數據進行緩存,提高二次加載速度;對於新增或者刪除數據經過 DiffUtil 來進行局部刷新數據,而不是一味地全局刷新數據。github

佈局優化

減小過渡繪製

減小布局層級,能夠考慮使用自定義 View 來減小層級,或者更合理地設置佈局來減小層級,不推薦在 RecyclerView 中使用 ConstraintLayout,有不少開發者已經反映了使用它效果更差,相關連接有:Is ConstraintLayout that slow?constraintlayout 1.1.1 not work well in listview面試

減小 xml 文件 inflate 時間

這裏的 xml 文件不只包括 layout 的 xml,還包括 drawable 的 xml,xml 文件 inflate 出 ItemView 是經過耗時的 IO 操做,尤爲當 Item 的複用概率很低的狀況下,隨着 Type 的增多,這種 inflate 帶來的損耗是至關大的,此時咱們能夠用代碼去生成佈局,即 new View() 的方式,只要搞清楚 xml 中每一個節點的屬性對應的 API 便可。緩存

減小 View 對象的建立

一個稍微複雜的 Item 會包含大量的 View,而大量的 View 的建立也會消耗大量時間,因此要儘量簡化 ItemView;設計 ItemType 時,對多 ViewType 可以共用的部分儘可能設計成自定義 View,減小 View 的構造和嵌套。bash

其餘

其餘並不表明不重要,而是我不能把他們進行分類哈,其中可能某些操做會對你的 RecyclerView 有很大的優化。網絡

  • 升級 RecycleView 版本到 25.1.0 及以上使用 Prefetch 功能,可參考 RecyclerView 數據預取異步

  • 若是 Item 高度是固定的話,可使用 RecyclerView.setHasFixedSize(true); 來避免 requestLayout 浪費資源;ide

  • 設置 RecyclerView.addOnScrollListener(listener); 來對滑動過程當中中止加載的操做。

  • 若是不要求動畫,能夠經過 ((SimpleItemAnimator) rv.getItemAnimator()).setSupportsChangeAnimations(false); 把默認動畫關閉來提高效率。

  • TextView 使用 String.toUpperCase 來替代 android:textAllCaps="true"

  • TextView 使用 StaticLayout 或者 DynamicLayout 的自定義 View 來代替它。

  • 經過重寫 RecyclerView.onViewRecycled(holder) 來回收資源。

  • 經過 RecycleView.setItemViewCacheSize(size); 來加大 RecyclerView 的緩存,用空間換時間來提升滾動的流暢性。

  • 若是多個 RecycledViewAdapter 是同樣的,好比嵌套的 RecyclerView 中存在同樣的 Adapter,能夠經過設置 RecyclerView.setRecycledViewPool(pool); 來共用一個 RecycledViewPool

  • ItemView 設置監聽器,不要對每一個 Item 都調用 addXxListener,應該你們公用一個 XxListener,根據 ID 來進行不一樣的操做,優化了對象的頻繁建立帶來的資源消耗。

  • 經過 getExtraLayoutSpace 來增長 RecyclerView 預留的額外空間(顯示範圍以外,應該額外緩存的空間),以下所示:

    new LinearLayoutManager(this) {
        @Override
        protected int getExtraLayoutSpace(RecyclerView.State state) {
            return size;
        }
    };
    複製代碼

結語

我正在打造一個幫助 Android 開發者們拿到更好 offer 的面試庫————安卓 offer 收割基,歡迎 star,以爲不錯的能夠持續關注,有興趣的能夠一塊兒加入進來和我一同打造。

相關文章
相關標籤/搜索