Android 布局優(yōu)化

布局優(yōu)化主要從以下幾點(diǎn)進(jìn)行著手

  • 減少布局層次 和 復(fù)雜度
  • 優(yōu)化繪制流程
  • 按需加載布局

減少布局層次 和 復(fù)雜度

  1. 首先我們可以通過以下工具分析界面布局的結(jié)構(gòu)
  • 查看布局樹工具:Hierarchy Viewer --> SDK tools下/ 或者使用AS的 Tools-->Layout Inspector


    image.png

    除此之外我們可以查看界面的繪制分析


    image.png
image.png

三個(gè)點(diǎn)分別表示:Measure , layout , draw
Mearsure 紅:嵌套R(shí)elativeLayout空繁,或者嵌套LinearLayout 使用了weight 屬性
Layout 紅:布局嵌套層次太深
Draw 紅:自定義view 繪制有問題

  • 打開手機(jī)的debug模式下Debug GPU overdraw可以查看過度繪制的區(qū)域


    繪制.jpg
  1. 通過以上的布局分析可以使用以下方法減少布局的層次和復(fù)雜度
  • 使用合適的布局結(jié)構(gòu)尚骄,減少不必要的布局嵌套,一般的建議規(guī)則如下

1.盡量多使用 ConstraintLayout茧球、RelativeLayout麸澜、LinearLayout
2.盡量使用 ConstraintLayout
3.在布局的層級(jí)相同的情況下税娜,使用 LinearLayout 代替 RelativeLayout
4.在布局復(fù)雜或者層級(jí)過深的時(shí)候,使用 RelativeLayout 代替 LinearLayout 使界面層級(jí)扁平化拴事,降低層級(jí)

  • 通過使用 include merge 復(fù)用布局践剂,減少布局層次
  • 排查background,減少不必的背景色設(shè)置溉知,減少過度繪制
    移除window 的背景色\ListView 與 Item\ViewPager 與 Fragment
// 方式1:在應(yīng)用的主題中添加如下的一行屬性
    <item name="android:windowBackground">@android:color/transparent</item>
    <!-- 或者 -->
    <item name="android:windowBackground">@null</item>

// 方式2:在 BaseActivity 的 onCreate() 方法中使用下面的代碼移除
    getWindow().setBackgroundDrawable(null);
    <!-- 或者 -->
    getWindow().setBackgroundDrawableResource(android.R.color.transparent);

優(yōu)化繪制流程

  1. 對(duì)onDraw進(jìn)行優(yōu)化
  1. 減少onDraw中局部變量的聲明 -- 由于被頻繁調(diào)用變量的生成和銷毀會(huì)造成一定的開銷陨瘩,局部變量過多會(huì)造成系統(tǒng)的消耗
  2. 減少onDraw 中耗時(shí)操作 -- 由于官方建議每幀繪制頻率為60fsp腕够,即要求每幀繪制時(shí)間<=16sm,Android 系統(tǒng)每隔16ms發(fā)出ASYNC信號(hào)舌劳,出發(fā)對(duì)UI進(jìn)行渲染
    android 官方文檔:https://developer.android.google.cn/topic/performance/rendering
    可以使用debug 中的工具(Profile GPU Rendering)分析每幀繪制的時(shí)間帚湘,推薦文章
    http://www.reibang.com/p/6b715f3d47e4
    也可以通過將內(nèi)容輸出到文件中進(jìn)行分析蒿囤,推薦文章:
    https://www.cnblogs.com/sinkv/p/9773256.html
  1. 使用局部繪制api
// 規(guī)定繪制區(qū)域客们,防止其他區(qū)域過度繪制
canvas.save();
canvas.clipRect(xx,xx,xx,xx);
canvas.restore();
//可以使用canvas.quickreject()來判斷是否沒和某個(gè)矩形相交,從而跳過那些非矩形區(qū)域內(nèi)的繪制操作

按需加載布局

  1. 使用viewStub 按需加載布局材诽,可以提高view 初始加載的速度

新加:

  1. 除了以上方法我們還可以通過使用Lint 工具進(jìn)行排查,一般我們需要關(guān)注的Lint 排查點(diǎn):


    image.png
  2. 不要阻塞UI線程恒傻,將耗時(shí)任務(wù)放到子線程中操作脸侥,可以使用DDMS中的TraceView 進(jìn)行分析,查看主線程中的耗時(shí)操作
  3. 使用AsyncLayoutInflater 異步加載布局,不過再使用中存下來一下問題
  1. 使用Factory 監(jiān)控view 的創(chuàng)建時(shí)間
LayoutInflaterCompat.setFactory2(getLayoutInflater(), new LayoutInflater.Factory2() {
   @Nullable
   @Override
   public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
       //1.配合getDelegate().createView來做高版本控件的兼容適配盈厘。
       //2.單個(gè)View創(chuàng)建耗時(shí)統(tǒng)計(jì)睁枕。
       long time = System.currentTimeMillis();
       View view = getDelegate().createView(parent, name, context, attrs);
       Log.i("TAG", name + "  cost: " + (System.currentTimeMillis() - time));
       return view;
   }

   @Nullable
   @Override
   public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
       return null;
   }
});
2020-03-11 16:43:07.389 17078-17078/com.stan.topnews I/Perf: Connecting to perf service.
2020-03-11 16:43:07.567 17078-17078/com.stan.topnews I/perf: LinearLayout  cost: 13
2020-03-11 16:43:07.569 17078-17078/com.stan.topnews I/perf: ViewStub  cost: 0
2020-03-11 16:43:07.634 17078-17078/com.stan.topnews I/perf: TextView  cost: 16
2020-03-11 16:43:07.637 17078-17078/com.stan.topnews I/perf: TextView  cost: 3

參考文章:https://mp.weixin.qq.com/s/ii07I8Cy80MqjsqKkns_WQ

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沸手,隨后出現(xiàn)的幾起案子外遇,更是在濱河造成了極大的恐慌,老刑警劉巖契吉,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跳仿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捐晶,警方通過查閱死者的電腦和手機(jī)菲语,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惑灵,“玉大人山上,你說我怎么就攤上這事∮⒅В” “怎么了佩憾?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)干花。 經(jīng)常有香客問我妄帘,道長(zhǎng),這世上最難降的妖魔是什么把敢? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任寄摆,我火速辦了婚禮,結(jié)果婚禮上修赞,老公的妹妹穿的比我還像新娘婶恼。我一直安慰自己桑阶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布勾邦。 她就那樣靜靜地躺著蚣录,像睡著了一般。 火紅的嫁衣襯著肌膚如雪眷篇。 梳的紋絲不亂的頭發(fā)上萎河,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音蕉饼,去河邊找鬼虐杯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛昧港,可吹牛的內(nèi)容都是我干的擎椰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼创肥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼达舒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叹侄,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤巩搏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后趾代,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贯底,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年稽坤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了丈甸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尿褪,死狀恐怖睦擂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杖玲,我是刑警寧澤顿仇,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站摆马,受9級(jí)特大地震影響臼闻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜囤采,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一述呐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蕉毯,春花似錦乓搬、人聲如沸思犁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽激蹲。三九已至,卻和暖如春江掩,著一層夾襖步出監(jiān)牢的瞬間学辱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工环形, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留策泣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓抬吟,卻偏偏與公主長(zhǎng)得像着降,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拗军,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354