激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

高校合作1:010-59833514 ?咨詢電話:400-810-1418 服務(wù)與監(jiān)督電話:400-810-1418轉(zhuǎn)接2

android性能優(yōu)化(一)之UI渲染優(yōu)化

發(fā)布時(shí)間:2024-09-05 18:58:26 瀏覽量:114次

閱讀本文大概需要 2.6 分鐘。

在眾多高頻面試題中,Android性能優(yōu)化幾乎可以說是必問的考題。

而此題一出,一場惡戰(zhàn)已然拉開序幕,因?yàn)榇嗽掝}牽扯面非常廣,絕非三言兩語就能夠聊完。因此,非常有必要對性能優(yōu)化做一下系統(tǒng)性的總結(jié)。

此篇作為性能優(yōu)化系列開篇,是因?yàn)閁I渲染優(yōu)化最為初級,且雜項(xiàng)很多,面試時(shí)可以作為回答的起點(diǎn)。

對于UI渲染優(yōu)化,記住一個(gè)宗旨:盡量減少 layout 布局嵌套層級和 View 個(gè)數(shù)。后面幾項(xiàng)其實(shí)都是圍繞著這個(gè)宗旨來做具體的優(yōu)化的。

減少嵌套層級是減少 View 樹的深度,原因一是如果 View 樹過深,會(huì)導(dǎo)致 findViewById() 方法查找耗時(shí),因?yàn)?findViewById 始終是從 rootView 開始深度優(yōu)先遍歷,二是會(huì)導(dǎo)致繪制重疊,從而造成過度繪制。

減少 View 個(gè)數(shù),不言而喻能用最少的 View 個(gè)數(shù)實(shí)現(xiàn) UI 效果,能夠避免不必要的測量,放置,繪制的計(jì)算時(shí)間,和 View 的查找時(shí)間。

從代碼的可讀性和可維護(hù)性上來講,最簡潔的東西也是最好的。

一. 布局優(yōu)化

1)盡量選用 RelativeLayout,ConstraintLayout,LinearLayout,并發(fā)揮它們的特性使布局扁平化。同等扁平的情況下,選用 LinearLayout 性能更佳。

2)利用系統(tǒng)提供 View 的特殊屬性,比如 TextView 的 drawableStart 屬性等設(shè)置 icon,就沒有必要再增加一個(gè) ImageView。TextView 滑動(dòng)屬性來避免嵌套一層 ScrollView。

3)include 一個(gè) layout 時(shí),可以考慮使用 merge 標(biāo)簽,如果布局的最外層和它所在的父容器控件相同,那么使用 merge 可以減少一個(gè)嵌套層級。

4)當(dāng)某個(gè)布局的顯現(xiàn)需要條件時(shí),比如斷網(wǎng),獲取數(shù)據(jù)失敗等顯示的 UI,可以考慮使用 ViewStub。其本質(zhì)是一個(gè)寬高為 0 的 View,非常輕量級,當(dāng)需要顯示時(shí)再 inflate 或者 visible=true 才會(huì)加載其布局。

5)使用 LinearLayout 自帶的 divider 屬性實(shí)現(xiàn)分割線,而不是在布局中手動(dòng)添加一個(gè)額外的 View 作為分割線。

6)使用 Space 控件(而非 View,LinearLayout 等)進(jìn)行合理的占位。其本質(zhì)是一個(gè) onDraw 實(shí)現(xiàn)為空的 View,因此它只占位置,而不去渲染,使用它來進(jìn)行占位填充比其他控件更加高效。

二. 自定義 view 優(yōu)化

1)onDraw 中避免對象的分配。原因是 onDraw 會(huì)執(zhí)行多次,將導(dǎo)致頻繁的 GC,內(nèi)存抖動(dòng),損耗性能。

2)使用 Canvas 的 ClipRect 方法避免過度繪制。

三. 過度繪制

所謂過度繪制,就是 GPU 在同一區(qū)域進(jìn)行了不必要的多次繪制。如果進(jìn)行真機(jī)調(diào)試,打開“調(diào)試 GPU 過度繪制”,就能看到不同的區(qū)域有不同的顏色,表示過度繪制嚴(yán)重的程度。

過度繪制的原因就是嵌套層級過深,而且設(shè)置了多余的背景色和不可見區(qū)域的繪制所導(dǎo)致。

1)在合適的地方設(shè)置背景。

比如要對 Activity 設(shè)置背景顏色,無需在其根 Layout 上設(shè)置其 background,因?yàn)橄到y(tǒng)本身就是把 Activity 的 xml 布局添加到一個(gè)叫“content”的 FrameLayout 中,Android 系統(tǒng)本身已經(jīng)對這個(gè) FrameLayout 設(shè)置了背景顏色。

如果我們在 layout.xml 的根 View 中再設(shè)置背景顏色,就相當(dāng)于 GPU 在同一區(qū)域繪制了 2 次背景色,導(dǎo)致過度繪制。

解決的辦法有 2 種:

public class MyActivity extends AppCompatActivity { @Override  protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //在 setContentView 之前 findViewById(android.R.id.content).setBackgroundResource(xxx); setContentView(R.layout.xxx); //在自己的根 layout 中設(shè)置背景}
public class MyActivity extends AppCompatActivity { @Override  protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState);  setContentView(R.layout.xxx); //在自己的根 layout 中設(shè)置背景 getWindow().setBackgroundDrawable(null) //在 setContentView 之后}

2)不可見區(qū)域不要繪制,ClipRect & QuickReject。

當(dāng)我們在自定義 View 中用到 ClipRect 時(shí),請只在 ClipRect 這個(gè)可見的矩形區(qū)域內(nèi)進(jìn)行繪制,而且通過 QuickReject 來判斷另一個(gè)繪制的矩形區(qū)域是否和 ClipRect 所在矩形區(qū)域有相交,若無,則可避免區(qū)域外的繪制。

一切從 android 的 handler 說起(一)之 message

一切從 android 的 handler 說起(二)之 threadLocal

一切從 android 的 handler 說起(三)之 UI 線程不卡頓

一切從 android 的 handler 說起(四)之 postDelay 原理

一切從 android 的 handler 說起(五)之觸摸事件模型

一切從 android 的 handler 說起(六)之生命周期來源

一切從 android 的 handler 說起(七)之 Handler 內(nèi)存泄露


進(jìn)入公眾號,回復(fù)“程序員“可以領(lǐng)取一份計(jì)算機(jī)技術(shù)電子書福利合集

歡迎轉(zhuǎn)發(fā),關(guān)注公眾號 火星時(shí)代

每天幾分鐘,掌握一個(gè)硬核面試知識(shí)點(diǎn)

熱門課程推薦

熱門資訊

請綁定手機(jī)號

x

同學(xué)您好!

您已成功報(bào)名0元試學(xué)活動(dòng),老師會(huì)在第一時(shí)間與您取得聯(lián)系,請保持電話暢通!
確定