成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【騰訊Bugly干貨分享】Android ListView與RecyclerView對(duì)比淺析--緩存

wangzy2019 / 1538人閱讀

摘要:數(shù)據(jù)源頻繁更新的場(chǎng)景,如彈幕等的優(yōu)勢(shì)會(huì)非常明顯進(jìn)一步來(lái)講,結(jié)論是列表頁(yè)展示界面,需要支持動(dòng)畫,或者頻繁更新,局部刷新,建議使用,更加強(qiáng)大完善,易擴(kuò)展其它情況如微信卡包列表頁(yè)兩者都,但在使用上會(huì)更加方便,快捷。

本文來(lái)自于騰訊bugly開(kāi)發(fā)者社區(qū),非經(jīng)作者同意,請(qǐng)勿轉(zhuǎn)載,原文地址:http://dev.qq.com/topic/5811d...

作者:黃寧源

一,背景

RecyclerView是谷歌官方出的一個(gè)用于大量數(shù)據(jù)展示的新控件,可以用來(lái)代替?zhèn)鹘y(tǒng)的ListView,更加強(qiáng)大和靈活。

最近,自己負(fù)責(zé)的業(yè)務(wù),也遇到這樣的一個(gè)問(wèn)題,關(guān)于是否要將ListView替換為RecyclerView?

秉承著實(shí)事求是的作風(fēng),弄清楚RecyclerView是否有足夠的吸引力替換掉ListView,我從性能這一角度出發(fā),研究RecyclerView和ListView二者的緩存機(jī)制,并得到了一些較有益的"結(jié)論",待我慢慢道來(lái)。

同時(shí)也希望能通過(guò)本文,讓大家快速了解RecyclerView與ListView在緩存機(jī)制上的一些區(qū)別,在使用上也更加得心應(yīng)手吧。

PS:相關(guān)知識(shí):
ListView與RecyclerView緩存機(jī)制原理大致相似,如下圖所示:

過(guò)程中,離屏的ItemView即被回收至緩存,入屏的ItemView則會(huì)優(yōu)先從緩存中獲取,只是ListView與RecyclerView的實(shí)現(xiàn)細(xì)節(jié)有差異.(這只是緩存使用的其中一個(gè)場(chǎng)景,還有如刷新等)

PPS:本文不貼出詳細(xì)代碼,結(jié)合源碼食用更佳!

二. 正文 2.1 緩存機(jī)制對(duì)比
1. 層級(jí)不同:

RecyclerView比ListView多兩級(jí)緩存,支持多個(gè)離ItemView緩存,支持開(kāi)發(fā)者自定義緩存處理邏輯,支持所有RecyclerView共用同一個(gè)RecyclerViewPool(緩存池)。

具體來(lái)說(shuō):
ListView(兩級(jí)緩存):

RecyclerView(四級(jí)緩存):

ListView和RecyclerView緩存機(jī)制基本一致:

1). mActiveViews和mAttachedScrap功能相似,意義在于快速重用屏幕上可見(jiàn)的列表項(xiàng)ItemView,而不需要重新createView和bindView;

2). mScrapView和mCachedViews + mReyclerViewPool功能相似,意義在于緩存離開(kāi)屏幕的ItemView,目的是讓即將進(jìn)入屏幕的ItemView重用.

3). RecyclerView的優(yōu)勢(shì)在于a.mCacheViews的使用,可以做到屏幕外的列表項(xiàng)ItemView進(jìn)入屏幕內(nèi)時(shí)也無(wú)須bindView快速重用;b.mRecyclerPool可以供多個(gè)RecyclerView共同使用,在特定場(chǎng)景下,如viewpaper+多個(gè)列表頁(yè)下有優(yōu)勢(shì).客觀來(lái)說(shuō),RecyclerView在特定場(chǎng)景下對(duì)ListView的緩存機(jī)制做了補(bǔ)強(qiáng)和完善。

2. 緩存不同:

1). RecyclerView緩存RecyclerView.ViewHolder,抽象可理解為:
View + ViewHolder(避免每次createView時(shí)調(diào)用findViewById) + flag(標(biāo)識(shí)狀態(tài));
2). ListView緩存View。

緩存不同,二者在緩存的使用上也略有差別,具體來(lái)說(shuō):
ListView獲取緩存的流程:

RecyclerView獲取緩存的流程:

1). RecyclerView中mCacheViews(屏幕外)獲取緩存時(shí),是通過(guò)匹配pos獲取目標(biāo)位置的緩存,這樣做的好處是,當(dāng)數(shù)據(jù)源數(shù)據(jù)不變的情況下,無(wú)須重新bindView:

而同樣是離屏緩存,ListView從mScrapViews根據(jù)pos獲取相應(yīng)的緩存,但是并沒(méi)有直接使用,而是重新getView(即必定會(huì)重新bindView),相關(guān)代碼如下:

//AbsListView源碼:line2345
//通過(guò)匹配pos從mScrapView中獲取緩存
final View scrapView = mRecycler.getScrapView(position);
//無(wú)論是否成功都直接調(diào)用getView,導(dǎo)致必定會(huì)調(diào)用createView
final View child = mAdapter.getView(position, scrapView, this);
if (scrapView != null) {
    if (child != scrapView) {
        mRecycler.addScrapView(scrapView, position);
    } else {
        ...
    }
}

2). ListView中通過(guò)pos獲取的是view,即pos-->view;
RecyclerView中通過(guò)pos獲取的是viewholder,即pos --> (view,viewHolder,flag);
從流程圖中可以看出,標(biāo)志flag的作用是判斷view是否需要重新bindView,這也是RecyclerView實(shí)現(xiàn)局部刷新的一個(gè)核心.

2.2 局部刷新

由上文可知,RecyclerView的緩存機(jī)制確實(shí)更加完善,但還不算質(zhì)的變化,RecyclerView更大的亮點(diǎn)在于提供了局部刷新的接口,通過(guò)局部刷新,就能避免調(diào)用許多無(wú)用的bindView.

(RecyclerView和ListView添加,移除Item效果對(duì)比)

結(jié)合RecyclerView的緩存機(jī)制,看看局部刷新是如何實(shí)現(xiàn)的:
以RecyclerView中notifyItemRemoved(1)為例,最終會(huì)調(diào)用requestLayout(),使整個(gè)RecyclerView重新繪制,過(guò)程為:
onMeasure()-->onLayout()-->onDraw()

其中,onLayout()為重點(diǎn),分為三步:

dispathLayoutStep1():記錄RecyclerView刷新前列表項(xiàng)ItemView的各種信息,如Top,Left,Bottom,Right,用于動(dòng)畫的相關(guān)計(jì)算;

dispathLayoutStep2():真正測(cè)量布局大小,位置,核心函數(shù)為layoutChildren();

dispathLayoutStep3():計(jì)算布局前后各個(gè)ItemView的狀態(tài),如Remove,Add,Move,Update等,如有必要執(zhí)行相應(yīng)的動(dòng)畫.

其中,layoutChildren()流程圖:

當(dāng)調(diào)用notifyItemRemoved時(shí),會(huì)對(duì)屏幕內(nèi)ItemView做預(yù)處理,修改ItemView相應(yīng)的pos以及flag(流程圖中紅色部分):

當(dāng)調(diào)用fill()中RecyclerView.getViewForPosition(pos)時(shí),RecyclerView通過(guò)對(duì)pos和flag的預(yù)處理,使得bindview只調(diào)用一次.

需要指出,ListView和RecyclerView最大的區(qū)別在于數(shù)據(jù)源改變時(shí)的緩存的處理邏輯,ListView是"一鍋端",將所有的mActiveViews都移入了二級(jí)緩存mScrapViews,而RecyclerView則是更加靈活地對(duì)每個(gè)View修改標(biāo)志位,區(qū)分是否重新bindView。

三.結(jié)論

在一些場(chǎng)景下,如界面初始化,滑動(dòng)等,ListView和RecyclerView都能很好地工作,兩者并沒(méi)有很大的差異:

文章的開(kāi)頭便拋出了這樣一個(gè)問(wèn)題,微信Android客戶端卡券模塊,大部分UI都是以列表頁(yè)的形式展示,實(shí)現(xiàn)方式為L(zhǎng)istView,是否有必要將其替換成RecyclerView呢?

答案是否定的,從性能上看,RecyclerView并沒(méi)有帶來(lái)顯著的提升,不需要頻繁更新,暫不支持用動(dòng)畫,意味著RecyclerView優(yōu)勢(shì)也不太明顯,沒(méi)有太大的吸引力,ListView已經(jīng)能很好地滿足業(yè)務(wù)需求。

數(shù)據(jù)源頻繁更新的場(chǎng)景,如彈幕:http://www.jianshu.com/p/2232...等RecyclerView的優(yōu)勢(shì)會(huì)非常明顯;

進(jìn)一步來(lái)講,結(jié)論是:
列表頁(yè)展示界面,需要支持動(dòng)畫,或者頻繁更新,局部刷新,建議使用RecyclerView,更加強(qiáng)大完善,易擴(kuò)展;其它情況(如微信卡包列表頁(yè))兩者都OK,但ListView在使用上會(huì)更加方便,快捷。

Ps:僅從一個(gè)角度做了對(duì)比,盲人摸象,有誤跪求指正。

四.參考資料 1. ListView

Android-23源碼

Android ListView工作原理解析,帶你從源碼的角度徹底理解:http://blog.csdn.net/guolin_b...

Android自己動(dòng)手寫ListView學(xué)習(xí)其原理:http://blog.csdn.net/androidd...

2. RecyclerView

RecyclerView-v7-23.4.0源碼

RecyclerView剖析:http://blog.csdn.net/qq_23012...

RecyclerView剖析:http://blog.csdn.net/qq_23012...


更多精彩內(nèi)容歡迎關(guān)注bugly的微信公眾賬號(hào):

騰訊 Bugly是一款專為移動(dòng)開(kāi)發(fā)者打造的質(zhì)量監(jiān)控工具,幫助開(kāi)發(fā)者快速,便捷的定位線上應(yīng)用崩潰的情況以及解決方案。智能合并功能幫助開(kāi)發(fā)同學(xué)把每天上報(bào)的數(shù)千條 Crash 根據(jù)根因合并分類,每日日?qǐng)?bào)會(huì)列出影響用戶數(shù)最多的崩潰,精準(zhǔn)定位功能幫助開(kāi)發(fā)同學(xué)定位到出問(wèn)題的代碼行,實(shí)時(shí)上報(bào)可以在發(fā)布后快速的了解應(yīng)用的質(zhì)量情況,適配最新的 iOS, Android 官方操作系統(tǒng),鵝廠的工程師都在使用,快來(lái)加入我們吧!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/61828.html

相關(guān)文章

  • 博客 - 收藏集 - 掘金

    摘要:技術(shù)之類加載機(jī)制掘金類加載機(jī)制是語(yǔ)言的一大亮點(diǎn),使得類可以被動(dòng)態(tài)加載到虛擬機(jī)中。玩轉(zhuǎn)仿探探卡片式滑動(dòng)效果掘金講起本篇博客的歷史起源,估計(jì)有一段歷史了。 Java 技術(shù)之類加載機(jī)制 - Android - 掘金類加載機(jī)制是 Java 語(yǔ)言的一大亮點(diǎn),使得 Java 類可以被動(dòng)態(tài)加載到 Java 虛擬機(jī)中。 這次我們拋開(kāi)術(shù)語(yǔ)和概念,從例子入手,由淺入深地講解 Java 的類加載機(jī)制。 本文...

    Shimmer 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<