Android性能優(yōu)化:那些不可忽略的繪制優(yōu)化


前言

  • Android開發(fā)中蹄衷,性能優(yōu)化策略十分重要
  • 本文主要講解性能優(yōu)化中的繪制優(yōu)化,希望你們會喜歡践惑。

目錄

示意圖

1. 影響的性能

繪制性能的好壞 主要影響 :Android應(yīng)用中的頁面顯示速度


2. 如何影響性能

繪制影響Android性能的實質(zhì):頁面的繪制時間

1個頁面通過遞歸 完成測量 & 繪制過程


3. 優(yōu)化思路

主要優(yōu)化方向是:

  1. 降低View.onDraw()的復(fù)雜度
  2. 避免過度繪制(Overdraw)

4. 具體優(yōu)化方案

  • 具體如下
示意圖
  • 下面,我將詳細(xì)分析每種優(yōu)化方案

4.1. 降低View.onDraw()的復(fù)雜度

4.1.1 onDraw()中不要創(chuàng)建新的局部對象

示意圖

4.1.2 避免onDraw()執(zhí)行大量 & 耗時操作

示意圖

4.2 避免過度繪制(Overdraw)

4.2.1 過度繪制的簡介

示意圖

4.2.2 過度繪制的表現(xiàn)形式

過度繪制 會導(dǎo)致屏幕顯示的色塊不同,具體如下


示意圖

附:示例說明

示意圖

4.2.3 過度繪制的優(yōu)化原則

很多 過度繪制是難以避免的稍走,如 上述實例的 文字 & 背景導(dǎo)致的過度繪制,只能盡可能避免過度繪制:

  1. 盡可能地控制 過度繪制的次數(shù) = 2 次(綠色)以下柴底,藍(lán)色最理想
  2. 盡可能避免 過度繪制的粉色 & 紅色情況
  3. 不允許 3 次以上的過度繪制(淡紅色)面積 超過 屏幕大小的 1/4

4.2.4 優(yōu)化方案

  1. 移除默認(rèn)的 Window 背景
  2. 移除 控件中不必要的背景
  3. 減少布局文件的層級(嵌套)
  4. 自定義控件View優(yōu)化:使用 clipRect() 、 quickReject()

優(yōu)化方案1: 移除默認(rèn)的 Window 背景

  • 背景:一般應(yīng)用程序 默認(rèn) 繼承的主題 = windowBackground 粱胜,如默認(rèn)的 Light 主題:
<style name="Theme.Light">
    <item name="isLightTheme">true</item>
    <item name="windowBackground">@drawable/screen_background_selector_light</item>
    ...
</style>
  • 問題:一般情況下柄驻,該默認(rèn)的 Window 背景基本用不上:因背景都自定義設(shè)置
    若不移除,則導(dǎo)致所有界面都多 1 次繪制

  • 解決方案:移除默認(rèn)的 Window 背景

// 方式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)化方案2:移除 控件中不必要的背景

如2個常見場景:

  • 場景1:ListViewItem
    列表頁(ListView) 與 其內(nèi)子控件(Item)的背景相同 = 白色焙压,故可移除子控件(Item)布局中的背景
示意圖
  • 場景2:ViewPagerFragment
    對于1個ViewPager + 多個 Fragment 組成的首頁界面鸿脓,若每個Fragment 都設(shè)有背景色,即 ViewPager 則無必要設(shè)置涯曲,可移除
示意圖

關(guān)于更多場景野哭,可使用工具 Hierarchy View 查看,具體請看文章: 過渡繪制的使用工具:Hierarchy View

優(yōu)化方案3:減少布局文件的層級(減少不必要的嵌套)

  • 原理:減少不必要的嵌套 ->> UI層級少 ->> 過度繪制的可能性低
  • 優(yōu)化方式:使用布局標(biāo)簽<merge> & 合適選擇布局類型

具體請看文章:Android性能優(yōu)化:這是一份詳細(xì)的布局優(yōu)化 指南(含<include>幻件、<Viewstub>拨黔、<merge>)

優(yōu)化方案4:自定義控件View優(yōu)化:使用 clipRect() 、 quickReject()

  • clipRect()
    1. 作用:給 Canvas 設(shè)置一個裁剪區(qū)域绰沥,只有在該區(qū)域內(nèi)才會被繪制篱蝇,區(qū)域之外的都不繪制
    2. 實例說明:DrawerLayout 布局 = 左抽屜布局
示意圖
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTim
    // ...僅貼出關(guān)鍵代碼

        // 1. 遍歷 DrawerLayout 的 child view,拿到抽屜布局
        for (int i = 0; i < childCount; i++) {
            final View v = getChildAt(i);
            if (v == child || v.getVisibility() != VISIBLE
                    || !hasOpaqueBackground(v) || !isDrawerView(v)
                    || v.getHeight() < height) {
                continue;
            }
            // a. 若是左抽屜布局
            // 則取抽屜布局的右邊界作為裁剪區(qū)的左邊界徽曲、設(shè)置原主布局的裁剪區(qū)域零截,如上圖裁剪區(qū)域
            if (checkDrawerViewAbsoluteGravity(v, Gravity.LEFT)) {
                final int vright = v.getRight();
                if (vright > clipLeft) clipLeft = vright;
            // b. 若是右抽屜布局
            // 則取抽屜布局的左邊界作為裁剪區(qū)的右邊界、設(shè)置原主布局的裁剪區(qū)域
            } else {
                final int vleft = v.getLeft();
                if (vleft < clipRight) clipRight = vleft;
            }
        }
        // 2. 通過clipRect()設(shè)置原主布局的顯示范圍 = 裁剪區(qū)域秃臣,使其僅在上圖中的紅框區(qū)域(即不阻礙抽屜布局的區(qū)域)顯示
       // 從而避免過度繪制
        canvas.clipRect(clipLeft, 0, clipRight, getHeight());
    }                
}
  • quickreject()
    1. 作用:判斷和某個矩形相交
    2. 具體措施:若判斷與矩形相交涧衙,則可跳過相交的區(qū)域,從而減少過度繪制

4.3 其他優(yōu)化方案

示意圖

總結(jié)

示意圖

至此奥此,關(guān)于繪制優(yōu)化的方案講解完畢弧哎。

5. 布局調(diào)優(yōu)工具

  • 背景
    盡管已經(jīng)注意到上述的優(yōu)化策略,但實際開發(fā)中難免還是會出現(xiàn)布局性能的問題
  • 解決方案
    使用 布局調(diào)優(yōu)工具

此處主要介紹 常用的:hierarchy viewer稚虎、Profile GPU Rendering傻铣、Systrace

5.1 Hierarchy Viewer

  • 簡介
    Android Studio 提供的UI性能檢測工具。

  • 作用
    可視化獲得UI布局設(shè)計結(jié)構(gòu) & 各種屬性信息祥绞,幫助我們優(yōu)化布局設(shè)計

即 :方便查看Activity布局非洲,各個View的屬性鸭限、布局測量-布局-繪制的時間

5.2 Profile GPU Rendering

  • 簡介
    一個 圖形監(jiān)測工具

  • 作用
    渲染、繪制性能追蹤

能實時反應(yīng)當(dāng)前繪制的耗時

  • 具體使用
    橫軸 = 時間两踏、縱軸 = 每幀的耗時败京;隨著時間推移,從左到右的刷新呈現(xiàn)

提供一個標(biāo)準(zhǔn)的耗時梦染,如果高于標(biāo)準(zhǔn)耗時赡麦,就表示當(dāng)前這一幀丟失

示意圖

更詳細(xì)使用請看: Profile GPU Rendering 使用指南

5.3 Systrace

  • 簡介
    Android 4.1以上版本提供的性能數(shù)據(jù)采樣 & 分析工具
  • 作用
    檢測 Android系統(tǒng)各個組件隨著時間的運行狀態(tài) & 提供解決方案
  1. 收集 等運行信息,從而幫助開發(fā)者更直觀地分析系統(tǒng)瓶頸帕识,改進(jìn)性能
    檢測范圍包括:Android 關(guān)鍵子系統(tǒng)(如WindowManagerServiceFramework 部分關(guān)鍵模塊)泛粹、服務(wù)、View系統(tǒng)
  2. 功能包括:跟蹤系統(tǒng)的I/O 操作肮疗、內(nèi)核工作隊列晶姊、CPU 負(fù)載等,在 UI 顯示性能分析上提供很好的數(shù)據(jù)伪货,特別是在動畫播放不流暢们衙、渲染卡等問題上

6. 總結(jié)

  • 本文主要講解Android 性能優(yōu)化中的 繪制優(yōu)化
示意圖

請點贊碱呼!因為你的鼓勵是我寫作的最大動力蒙挑!

相關(guān)文章閱讀
Android開發(fā):最全面、最易懂的Android屏幕適配解決方案
Android事件分發(fā)機(jī)制詳解:史上最全面愚臀、最易懂
Android開發(fā):史上最全的Android消息推送解決方案
Android開發(fā):最全面忆蚀、最易懂的Webview詳解
Android開發(fā):JSON簡介及最全面解析方法!
Android四大組件:Service服務(wù)史上最全面解析
Android四大組件:BroadcastReceiver史上最全面解析


歡迎關(guān)注Carson_Ho的簡書!

不定期分享關(guān)于安卓開發(fā)的干貨姑裂,追求短蜓谋、平、快炭分,但卻不缺深度桃焕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捧毛,隨后出現(xiàn)的幾起案子观堂,更是在濱河造成了極大的恐慌,老刑警劉巖呀忧,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件师痕,死亡現(xiàn)場離奇詭異,居然都是意外死亡而账,警方通過查閱死者的電腦和手機(jī)胰坟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泞辐,“玉大人笔横,你說我怎么就攤上這事竞滓。” “怎么了吹缔?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵商佑,是天一觀的道長。 經(jīng)常有香客問我厢塘,道長茶没,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任晚碾,我火速辦了婚禮抓半,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘格嘁。我一直安慰自己笛求,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布讥蔽。 她就那樣靜靜地躺著,像睡著了一般画机。 火紅的嫁衣襯著肌膚如雪冶伞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天步氏,我揣著相機(jī)與錄音响禽,去河邊找鬼。 笑死荚醒,一個胖子當(dāng)著我的面吹牛芋类,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播界阁,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼侯繁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泡躯?” 一聲冷哼從身側(cè)響起贮竟,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎较剃,沒想到半個月后咕别,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡写穴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年惰拱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啊送。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡偿短,死狀恐怖欣孤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翔冀,我是刑警寧澤导街,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站纤子,受9級特大地震影響搬瑰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜控硼,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一泽论、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卡乾,春花似錦翼悴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至误堡,卻和暖如春古话,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锁施。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工陪踩, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悉抵。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓肩狂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親姥饰。 傳聞我的和親對象是個殘疾皇子傻谁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

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