?近期學(xué)習(xí)布局優(yōu)化以及渲染優(yōu)化蹂析,在網(wǎng)上搜索相關(guān)博文后,發(fā)現(xiàn)知識(shí)點(diǎn)比較統(tǒng)一碟婆,所以做個(gè)學(xué)習(xí)總結(jié)电抚,主要是方便自己掌握與運(yùn)用并且在之后要用到的時(shí)候可以回過(guò)頭來(lái)參考。
由于是初學(xué)者竖共,寫(xiě)的比較簡(jiǎn)單蝙叛,借鑒了比較多的其他博文的內(nèi)容,所以先貼出鏈接注明出處公给。
參考博文出處鏈接:
?? Android UI性能優(yōu)化實(shí)戰(zhàn) 識(shí)別繪制中的性能問(wèn)題 ?
?? Android性能優(yōu)化(二)之布局優(yōu)化面面觀(guān)??
?? Android性能優(yōu)化之布局優(yōu)化 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
一:Android 渲染機(jī)制
為了能夠使得APP流暢借帘,我們需要在每一幀16ms以?xún)?nèi)完成所有的CPU與GPU計(jì)算,繪制淌铐,渲染等等操作肺然。也就是幀率為60fps,為什么幀率要為60fps呢腿准,因?yàn)槿搜叟c大腦之間的協(xié)作無(wú)法感知超過(guò)60fps的畫(huà)面更新际起。開(kāi)發(fā)app的性能目標(biāo)就是保持60fps拾碌,這意味著每一幀你只有16ms=1000/60的時(shí)間來(lái)處理所有的任務(wù)。
所以作為開(kāi)發(fā)人員街望,要保證穩(wěn)定合適的幀率以避免卡頓校翔。
Overdraw(過(guò)度繪制):描述的是屏幕上的某個(gè)像素在同一幀的時(shí)間內(nèi)被繪制了多次。在多層次的UI結(jié)構(gòu)里面灾前,如果不可見(jiàn)的UI也在做繪制的操作防症,就會(huì)導(dǎo)致某些像素區(qū)域被繪制了多次,浪費(fèi)大量的CPU以及GPU資源哎甲。(可以通過(guò)開(kāi)發(fā)者選項(xiàng)蔫敲,打開(kāi)Show GPU Overdraw的選項(xiàng),觀(guān)察UI上的Overdraw情況)炭玫。
具體梯度如下圖所示:
當(dāng)開(kāi)啟開(kāi)發(fā)者選項(xiàng)中的調(diào)試GPU過(guò)度繪制中的顯示過(guò)度繪制區(qū)域后燕偶,進(jìn)入到要看的UI界面,可以查看到础嫡。如若大部分為4X的紅色指么,則需要注意布局中的一些問(wèn)題,因?yàn)槿绻鸒verdraw過(guò)于嚴(yán)重的話(huà)會(huì)嚴(yán)重影響性能榴鼎。
二:布局渲染性能檢測(cè)
了解了可能會(huì)發(fā)生的問(wèn)題之后要有解決的措施伯诬,而在解決之前必須要通過(guò)檢測(cè)來(lái)對(duì)性能進(jìn)行診斷。除了上述的GPU過(guò)度繪制顯示之外巫财,還有一種更為細(xì)致的盗似、定位到每個(gè)View級(jí)別的、有直觀(guān)樹(shù)形結(jié)構(gòu)的可視化檢測(cè)工具:Hierarchy Viewer
在真機(jī)無(wú)法使用的問(wèn)題以及詳細(xì)的使用步驟可見(jiàn)鏈接:Hierarchy Viewer使用詳解
補(bǔ)充:采用android studio自帶的Android Lint也可以檢測(cè)布局是否重復(fù)平项、分析布局合理性赫舒。
三:布局優(yōu)化具體做法:
1:先設(shè)置 -> 開(kāi)發(fā)者選項(xiàng) -> 調(diào)試GPU過(guò)度繪制 -> 顯示GPU過(guò)度繪制? 進(jìn)入到對(duì)應(yīng)UI界面進(jìn)行檢測(cè).
移除不必要的background(檢測(cè)出現(xiàn)Overdraw嚴(yán)重時(shí)),檢查是否有多余的嵌套層數(shù)以及控件數(shù)
2:利用Hierarchy Viewer檢測(cè),去除不必要的嵌套闽瓢,減少嵌套層數(shù),減少多余的控件個(gè)數(shù)接癌。
3:RelativeLayout與LinearLayout的靈活選擇
首先,兩種布局各有各的優(yōu)勢(shì)扣讼,RelativeLayout比較靈活缺猛,能設(shè)置在布局中的任意位置,而LinearLayout比較簡(jiǎn)單易用椭符。那么如果在某些情況下兩種布局均可使用荔燎,我們應(yīng)該優(yōu)先使用哪種布局?這就涉及到了兩種布局的性能問(wèn)題销钝。
查閱資料:Android中RelativeLayout和LinearLayout性能分析?
查閱之后發(fā)現(xiàn)有咨,RelativeLayout不如后者快,其原因是:RelativeLayout需要對(duì)其子View進(jìn)行兩次measure過(guò)程(橫向縱向分別進(jìn)行一次排序測(cè)量來(lái)確定位置)蒸健。而LinearLayout則只需一次measure過(guò)程座享,所以顯然會(huì)快于RelativeLayout婉商,但是如果LinearLayout中有weight屬性,則也需要進(jìn)行兩次measure征讲,但即便如此,應(yīng)該仍然會(huì)比RelativeLayout的情況好一點(diǎn)橡娄。
但是Google默認(rèn)推薦的布局卻是RelativeLayout,這是因?yàn)樵诤芏嗲闆r下嵌套一層RelativeLayout便可實(shí)現(xiàn)布局效果诗箍,因?yàn)槠浜莒`活可設(shè)置任意位置,而LinearLayout這種只有vertical與horizontal兩個(gè)方向orientation設(shè)置的布局挽唉,在實(shí)現(xiàn)一些UI的時(shí)候可能會(huì)嵌套多層滤祖。官方的推薦目的是希望開(kāi)發(fā)者能采用盡量少的View層級(jí)來(lái)表達(dá)布局以實(shí)現(xiàn)性能最優(yōu),因?yàn)閺?fù)雜的View嵌套對(duì)性能的影響會(huì)比上述的measure兩次的影響要大一些瓶籽。
補(bǔ)充:在考慮手機(jī)屏幕尺寸以及分辨率的情況下匠童,只使用一個(gè)LinearLayout將所有的控件進(jìn)行展示并且從上到下的控件都設(shè)置了layout_marginTop或者layout_marginBottom的話(huà),可能會(huì)在低分辨率小尺寸的手機(jī)上擠掉一些內(nèi)容塑顺,這時(shí)需要在外層嵌套一個(gè)RelativeLayout并且在LinearLayout外設(shè)置會(huì)被擠掉的View控件汤求。所以遇到這種問(wèn)題嘗試RelativeLayout嵌套LinearLayout來(lái)解決。(兩者結(jié)合使用)
結(jié)論:在不影響層級(jí)深度的情況下,使用LinearLayout和FrameLayout而不是RelativeLayout严拒。同時(shí)扬绪,采用RelativeLayout并不會(huì)降低層級(jí)深度,所以此時(shí)在根節(jié)點(diǎn)上用LinearLayout是效率最高的裤唠。而若考慮層級(jí)深度的情況下用RelativeLayout比LinearLayout有更少的層級(jí)的話(huà)挤牛,優(yōu)先用RelativeLayout(官方推薦的理由)。所以种蘸,具體情況具體分析墓赴。
4:善用抽象布局標(biāo)簽:<include>,<merge>,以及按需載入的ViewStub
<include>:在一個(gè)布局文件中引入另一個(gè)布局文件的內(nèi)容,常用于引用一些公用的航瞭、調(diào)用多次的布局比如說(shuō)標(biāo)題欄诫硕,可方便統(tǒng)一修改。使代碼更清晰易懂刊侯,可防止多余的嵌套以及多余的控件
<merge>:merge可以用來(lái)合并布局痘括,減少布局的層級(jí)。merge多用于替換頂層FrameLayout或者include布局時(shí),用于消除因?yàn)橐貌季謱?dǎo)致的多余嵌套滔吠。
按需載入的ViewStub(輕量級(jí)視圖):代替?zhèn)鹘y(tǒng)的setVisibility為VISIBLE與GONE 來(lái)隱藏和顯示布局或控件纲菌,只是在需要的時(shí)候進(jìn)行調(diào)用載入,不會(huì)在一開(kāi)始的時(shí)候全部載入疮绷,那樣會(huì)影響整體性能翰舌。
5:巧用常見(jiàn)的控件的屬性
個(gè)人認(rèn)為這篇文章中的一些技巧比較精髓實(shí)用:一些你需要知道的布局優(yōu)化技巧
特別是里面的這些內(nèi)容:
用TextView同時(shí)顯示圖片和文字:利用TextView中的屬性
android:drawableLeft="@drawable/icon_1"
android:drawableRight="@drawable/icon_4"
android:drawablePadding="10dp"
便可以減少控件個(gè)數(shù)不用多添加兩個(gè)ImageView
使用TextView的行間距:
android:text="攬件方式:上門(mén)取件\n快遞公司:順豐快遞\n預(yù)約時(shí)間:9月6日 立即取件\n快遞費(fèi)用:等待稱(chēng)重確定價(jià)格"
再加上行間距android:lineSpacingExtra="8dp",省去了三個(gè)TextView的使用冬骚。
這些技巧雖然簡(jiǎn)單椅贱,但是不注意的話(huà)可能一般不會(huì)這樣用懂算,這樣用既方便,性能又不錯(cuò)庇麦。
四:布局優(yōu)化具體做法總結(jié)
1:移除不必要的background(利用GPU顯示繪制檢測(cè)出現(xiàn)Overdraw嚴(yán)重時(shí))
2:利用Hierarchy Viewer檢測(cè)计技,去除不必要的嵌套,減少嵌套層數(shù),減少多余的控件個(gè)數(shù)
3:RelativeLayout與LinearLayout的靈活選擇
4:善用抽象布局標(biāo)簽:<include>,<merge>以及按需載入的ViewStub
5:巧用常見(jiàn)的控件的屬性
最后山橄,第一次寫(xiě)文章垮媒,雖然是寫(xiě)給自己看的一篇總結(jié)性文章,借鑒了大量的優(yōu)秀博文航棱,但是發(fā)現(xiàn)寫(xiě)東西是件非常有趣的事情睡雇,然后又加上簡(jiǎn)書(shū)這個(gè)平臺(tái)的風(fēng)格簡(jiǎn)約,個(gè)人非常喜歡饮醇。當(dāng)然文章肯定有很多很多不足的地方它抱,如果您有什么意見(jiàn)或建議請(qǐng)一定要提出,我會(huì)慢慢改進(jìn)不斷提升朴艰,然后一直寫(xiě)下去观蓄。