性能優(yōu)化實(shí)踐(二)-布局優(yōu)化

一、簡介

眾所周知的Android系統(tǒng)每隔16ms重新繪制一次視圖府怯,也就是說你的app必須在16ms內(nèi)完成屏幕刷新的所有邏輯操作,這樣才能達(dá)到60幀/s,這個幀率對人的肉眼來說是流暢的药磺。如果達(dá)不到,用戶會感到卡頓煤伟。

另外癌佩,Android系統(tǒng)通過CPU和GPU共同完成視圖的渲染,大概流程如下:

1便锨、Cpu通過measure驼卖、layout、record鸿秆、execute幾個過程來對視圖進(jìn)行處理酌畜,得到一些多邊形和紋理。

2卿叽、Cpu通過指令(API:openGL ES)把這些多邊形桥胞、紋理發(fā)給gpu恳守。

3、Gpu進(jìn)行格柵化贩虾,格柵化就是將例如字符串催烘、按鈕、路徑或者形狀的一些高級對象缎罢,拆分到不同的像素上在屏幕上進(jìn)行顯示伊群。

二、優(yōu)化方向

CPU的優(yōu)化:從減輕加工View對象成Polygons和Texture來下手View Hierarchy中包涵了太多的沒有用的view策精,這些view根本就不會顯示在屏幕上面舰始,一旦觸發(fā)測量和布局操作,就會拖累應(yīng)用的性能表現(xiàn)咽袜。所以盡量減少不必要的View以及減少層級嵌套丸卷。

GPU優(yōu)化:從減輕柵格化來入手,避免同一個像素點(diǎn)被重復(fù)繪制多次询刹,也就是避免過度繪制(overdraw)

那么根據(jù)上述的兩個方向谜嫉,最終落地為兩點(diǎn):層級的優(yōu)化 、避免過度繪制凹联。 下面分別來分析沐兰。

三、檢查工具:

Lint :

Preferences /Editor /Inspections 下查看Lint的配置規(guī)則:

image.png

如果勾線了這兩項(xiàng)的話蔽挠,那么你運(yùn)行 Analyze/Inspect Code的時候僧鲁,就會把不合理的布局給你撈出來,默認(rèn)view數(shù)量是80象泵,深度是10寞秃,超過會報(bào)warning警告,也可以自定義lint規(guī)則來調(diào)整偶惠。

Layout Inspector:

當(dāng)然定位到具體代碼春寿,可以借助Layout Inspector,使用方法參考:性能優(yōu)化工具(六)-Layout Inspector

調(diào)試GPU過度繪制 & GPU呈現(xiàn)模式:

調(diào)試GPU過度繪制忽孽。使用方法參考:性能優(yōu)化工具(七)-調(diào)試GPU過度繪制 & GPU呈現(xiàn)模式分析

四绑改、優(yōu)化方案:

1)減少層級 (布局層級越少,加載速度越快)

  • 布局容器選擇:在不增加層級的情況下兄一,能用LinearLayout的就盡量別用RelativeLayout厘线,在使用LinearLayout會增加層級的情況下,那就盡量用RelativeLayout出革。原因是RelativeLayout允許子View橫向和縱向相互依賴造壮,那需要做兩次排序測量。但是就算這樣,也比增加層級要好耳璧。

  • 合理使用Merge:自定義控件的rootView 或者 include 的xml成箫, 如果最外層的rootView本身沒有太多意義,且內(nèi)部布局相對簡單旨枯,可以嘗試用merge來替代最外層相對簡單的FrameLayout和LinearLayout.復(fù)雜布局不建議使用蹬昌,merge本身的xml屬性可能做不到。

2)減少同一層級控件數(shù)量 (控件數(shù)量越少攀隔,加載速度越快)

ViewStub的使用皂贩,實(shí)現(xiàn)部分布局的懶加載。解決動態(tài)加載布局的場景昆汹,減少2選1明刷,N選1的場景的布局冗余,因?yàn)榫退悴伙@示筹煮,仍然會解析和測量這些布局。但是要注意使用特點(diǎn):程序的運(yùn)行期間居夹,某個布局在被Inflate后败潦,就不會有變化,才可以考慮用ViewStub劫扒。如果動態(tài)切來切去的那就沒法用沟饥。

3)減少和優(yōu)化控件屬性 (屬性越少,解析越快)

去掉控件的無用屬性

4)避免過度繪制

過度繪制指的是屏幕上某個像素點(diǎn)在同一幀的繪制時間內(nèi)湾戳,被繪制了多次。

  • 布局上:移除xml中非必須背景幼驶,移除window默認(rèn)背景 onCreate中 設(shè)置this.getWindow().setBackgroundDrawable(null);

  • 自定義控件上:onDraw里同一區(qū)域被繪制多次,可以使用canvas.clipRect()來優(yōu)化組件繪制的重疊部分氏淑,這個算是摳細(xì)節(jié)了,大部分情況下都不會使用守问。

5 ) 主線程耗時導(dǎo)致無法按時繪制完成

主線程不做耗時操作穆端,onDraw不做耗時操作。

可以使用 AsyncLayoutInflater 異步加載布局:

private void asyncInflated() {
        TextView textView = (TextView) findViewById(R.id.tv_async);
        final ViewGroup root = (ViewGroup) findViewById(R.id.ll_root);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncLayoutInflater asyncLayoutInflater = new AsyncLayoutInflater(OptActivity.this);
                asyncLayoutInflater.inflate(R.layout.layout_async, root, new AsyncLayoutInflater.OnInflateFinishedListener() {
                    @Override
                    public void onInflateFinished(View view, int resId, ViewGroup parent) {
                        parent.addView(view);
                    }
                });
            }
        });
    }

最后談?wù)勼w會,這部分的優(yōu)化,其實(shí)主要還是代碼規(guī)范的問題仅偎,一般來說在寫代碼的時候注意以上幾點(diǎn),基本上問題就不大座咆,除非要極致的扣細(xì)節(jié)那可能就還不夠,另外對于項(xiàng)目管理來說,可以寫一個比較好的lint module來幫助檢測項(xiàng)目規(guī)范弦牡,現(xiàn)在發(fā)現(xiàn)Lint確實(shí)非常實(shí)用。另外椭豫,還推薦下findBugs 這個插件,也非常不錯框都。

自定義Lint參考文章:

Android自定義Lint實(shí)踐
Android Studio 工具:Lint 代碼掃描工具(含自定義lint

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載谓罗,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末需纳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌妙蔗,老刑警劉巖穆役,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耿币,居然都是意外死亡梳杏,警方通過查閱死者的電腦和手機(jī)十性,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來支示,“玉大人嘴纺,你說我怎么就攤上這事栽渴〖饫ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵墅冷,是天一觀的道長纯路。 經(jīng)常有香客問我,道長寞忿,這世上最難降的妖魔是什么驰唬? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮腔彰,結(jié)果婚禮上叫编,老公的妹妹穿的比我還像新娘。我一直安慰自己霹抛,他們只是感情好搓逾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著上炎,像睡著了一般恃逻。 火紅的嫁衣襯著肌膚如雪雏搂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天寇损,我揣著相機(jī)與錄音凸郑,去河邊找鬼。 笑死矛市,一個胖子當(dāng)著我的面吹牛芙沥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浊吏,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼而昨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了找田?” 一聲冷哼從身側(cè)響起歌憨,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎墩衙,沒想到半個月后务嫡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漆改,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年心铃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挫剑。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡去扣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出樊破,到底是詐尸還是另有隱情愉棱,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布捶码,位于F島的核電站羽氮,受9級特大地震影響或链,放射性物質(zhì)發(fā)生泄漏惫恼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一澳盐、第九天 我趴在偏房一處隱蔽的房頂上張望祈纯。 院中可真熱鬧,春花似錦叼耙、人聲如沸腕窥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽簇爆。三九已至癞松,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間入蛆,已是汗流浹背响蓉。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哨毁,地道東北人枫甲。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像扼褪,于是被迫代替她去往敵國和親想幻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

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