Android性能優(yōu)化(二)布局優(yōu)化

布局優(yōu)化的主要思想其實很簡單,就是盡量減少布局文件的層級拂到,布局層級少了Android繪制時的工作量就少了归榕,程序運行時的性能自然就高了。
既然知道了主要思想那么接下來我們要做的工作就明朗了纳账。我們可以從兩方面著手進行優(yōu)化:

第一逛薇、優(yōu)化布局方案

在寫布局的過程中我們應(yīng)該避免無用的控件和層級,并且結(jié)合具體的使用場景去選擇ViewGroup疏虫。避免無用的控件很簡單永罚,不必多說啤呼。那如何去選擇性能更好的ViewGroup呢?這里的ViewGroup也就是我們常說的五大布局——FrameLayout呢袱、LinearLayout官扣、RelativeLayout、AbsoluteLayout羞福、TableLayout惕蹄。其中FrameLayout、LinearLayout治专、RelativeLayout是最常用的卖陵,因此這里只對這三種布局進行分析。

FameLayout

FrameLayout是五大布局中最簡單的一個布局张峰,在這個布局中泪蔫,整個界面被當(dāng)成一塊空白備用區(qū)域,所有的子元素都不能被指定放置的位置挟炬,它們統(tǒng)統(tǒng)放于這塊區(qū)域的左上角鸥滨,并且后面的子元素直接覆蓋在前面的子元素之上,將前面的子元素部分和全部遮擋谤祖。相同層級布局中 FrameLayout的效率也是最高的 占用內(nèi)存相對來說也是較小的婿滓。但是FrameLayout也有其缺陷:很難去組織多個子元素位置和關(guān)系。當(dāng)然如果只有一個子元素粥喜,當(dāng)然是使用FrameLayout最好凸主。這應(yīng)該也是為何作為頂級View的DecorView也是一個FrameLayout的原因吧。

LinearLayout與RelativeLayout性能PK

細心的同學(xué)應(yīng)該會發(fā)現(xiàn):無論是Eclipse還是Android Studio额湘,新建Blank Activity時默認的layout都是RelativeLayout卿吐。查詢資料你會發(fā)現(xiàn)這是由 android-sdk\tools\templates\activities\BlankActivity\root\res\layout\activity_simple.xml.ftl 這個文件定義的,也就是說這是Google的選擇锋华,而非IDE的選擇嗡官。而且google原文中也提到

A RelativeLayout is a very powerful utility for designing a user interface because it can eliminate nested view groups and keep your layout hierarchy flat, which improves performance. If you find yourself using several nested LinearLayout groups, you may be able to replace them with a single RelativeLayout.

大概的意思是“性能至上”, RelativeLayout 在性能上更好毯焕,因為在諸如 ListView 等控件中衍腥,使用 LinearLayout 容易產(chǎn)生多層嵌套的布局結(jié)構(gòu),這在性能上是不好的纳猫。而 RelativeLayout 因其原理上的靈活性婆咸,通常層級結(jié)構(gòu)都比較扁平,很多使用LinearLayout 的情況都可以用一個 RelativeLayout 來替代芜辕,以降低布局的嵌套層級尚骄,優(yōu)化性能。所以從這一點來看侵续,Google比較推薦開發(fā)者使用RelativeLayout倔丈,因此就將其作為Blank Activity的默認布局了憨闰。

有一篇博客寫的很不錯,通過實際測試以及源碼分析比較了兩者的性能需五,總結(jié)的也不錯起趾!請移步Android中RelativeLayout和LinearLayout性能分析。關(guān)于該博文中提到的“DecorView是一個垂直方向的LinearLayout”這句話是不準(zhǔn)確的警儒,通過看源碼我們可以知道DecorView其實是一個FrameLayout,而LinearLayout是作為它的唯一子元素眶根,構(gòu)成了我們熟知的DecorView上下兩部分(上面是標(biāo)題欄蜀铲,下面是內(nèi)容欄)的結(jié)構(gòu)。而我們經(jīng)常在Activity中用到的setContentView正是將我們的布局加到了下面部分的內(nèi)容欄属百,即content记劝。而content也是一個FrameLayout。

第二族扰,使用<include>厌丑、<merge>標(biāo)簽和ViewStub

這部分內(nèi)容算是比較基礎(chǔ),詳細的使用方式可以去看下官方文檔渔呵,下邊主要介紹下使用時需要注意到的點怒竿。

<include>標(biāo)簽

<include>標(biāo)簽主要用于布局重用,從而避免同樣的布局寫重復(fù)的代碼扩氢,它的使用如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/title_bar"
        layout="@layout/title_bar"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/string"/>
     ......
</LinearLayout>

其中layout="@layout/title_bar"指定了另外的一個布局title_bar.xml耕驰,一個應(yīng)用內(nèi)很多界面都會用到titlebar,通過這樣的方式录豺,這個布局的內(nèi)容就只需要寫一遍就可以了朦肘。需要注意的是:1、<include>除了android:id這個屬性只支持以 android:layout_開頭的屬性双饥,而且只要指定了這種屬性媒抠,那么也必須要指定 android:layout_width 和 android:layout_height,否則會直接報語法錯誤咏花。2趴生、如果指定了id或者
android:layout_*屬性,會直接覆蓋導(dǎo)入布局的根布局的相應(yīng)屬性迟螺,如果都沒有指定則會使用導(dǎo)入布局的根布局的屬性冲秽。

<merge>標(biāo)簽

在使用<include>標(biāo)簽時,可能會導(dǎo)致重復(fù)的布局嵌套矩父,加深布局的層級锉桑,從而使得加載變慢,這時我們會用到<merge>標(biāo)簽窍株。所以<merge>標(biāo)簽要和<include>標(biāo)簽配合使用民轴,用來減少布局中重復(fù)的層級攻柠,而且<merge>標(biāo)簽只能作為<include>指定的布局的根標(biāo)簽使用,這樣<merge>標(biāo)簽中包含的子元素后裸,就直接與 <include>平級瑰钮。
因此在使用<merge>標(biāo)簽時,我們需注意一點:<merge>標(biāo)簽內(nèi)的子元素會按照<include> 所在布局的布局方式來顯示微驶。所以我們在使用的時候需要特別注意布局類型浪谴!

ViewStub

在開發(fā)過程中,經(jīng)常會遇到這樣一種情況:有些布局在正常情況下不會顯示因苹,如網(wǎng)絡(luò)異常頁苟耻、空白頁等,雖然設(shè)置可見性View.GONE,但是在整個界面初始化的時候仍然會將其加載進來扶檐,所以增加了初始化時的消耗凶杖。這時我們就可以用到ViewStub,它提供了按需加載的功能款筑,在需要的時候才會將ViewStub中的布局加載到內(nèi)存智蝠,所以提高了初始化時的性能,從而也提高了程序的效率奈梳。
看源碼可以知道杈湾,ViewStub繼承了View,非常輕量級且寬 /高都是0攘须,因此它本身不參與任何的布局和繪制過程毛秘。它的使用方式也很簡單,下面是ViewStub的示例:

<ViewStub
        android:id="@+id/stub_import"
        android:inflatedId="@+id/layout_import"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/layout_net_error" />

其中stub_import是ViewStub的id阻课,而layout_import是layout/layout_net_error這個布局的根元素的id叫挟。需要加載ViewStub中的布局時,可以使用以下兩種方式:
( (ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
View errorLayout = ((ViewStub)findViewById(R.id.stub_import)).inflate();
需要注意的是:ViewStub一旦visible/inflated限煞,就會被它內(nèi)部的布局替換掉抹恳,而它自己也不再是整個布局中的一部分了。所以后面無法再使用ViewStub來控制布局了署驻。
由于ViewStub這種使用后就置空的策略奋献,所以當(dāng)需要在運行時不止一次的顯示和隱藏某個布局時,ViewStub是做不到的旺上,這時就只有使用View的可見性來控制了瓶蚂。另外,目前ViewStub還不支持<merge>標(biāo)簽宣吱。

布局優(yōu)化到這兒就結(jié)束了窃这,如果大家還有更好的想法可以提出,我們共同學(xué)習(xí)征候,謝謝杭攻!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末祟敛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子兆解,更是在濱河造成了極大的恐慌馆铁,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锅睛,死亡現(xiàn)場離奇詭異埠巨,居然都是意外死亡,警方通過查閱死者的電腦和手機现拒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門乖订,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人具练,你說我怎么就攤上這事√鹞蓿” “怎么了扛点?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長岂丘。 經(jīng)常有香客問我陵究,道長,這世上最難降的妖魔是什么奥帘? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任铜邮,我火速辦了婚禮,結(jié)果婚禮上寨蹋,老公的妹妹穿的比我還像新娘松蒜。我一直安慰自己,他們只是感情好已旧,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布秸苗。 她就那樣靜靜地躺著,像睡著了一般运褪。 火紅的嫁衣襯著肌膚如雪惊楼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天秸讹,我揣著相機與錄音檀咙,去河邊找鬼。 笑死璃诀,一個胖子當(dāng)著我的面吹牛弧可,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劣欢,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼侣诺,長吁一口氣:“原來是場噩夢啊……” “哼殖演!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起年鸳,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤趴久,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后搔确,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彼棍,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年膳算,在試婚紗的時候發(fā)現(xiàn)自己被綠了座硕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡涕蜂,死狀恐怖华匾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情机隙,我是刑警寧澤蜘拉,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站有鹿,受9級特大地震影響旭旭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜葱跋,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一持寄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧娱俺,春花似錦稍味、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至僵朗,卻和暖如春赖欣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背验庙。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工顶吮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粪薛。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓悴了,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子湃交,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容