
前言
- 在
Android開發(fā)中,性能優(yōu)化策略十分重要 - 本文主要講解性能優(yōu)化中的繪制優(yōu)化,希望你們會(huì)喜歡。
目錄

1. 影響的性能
繪制性能的好壞 主要影響 :Android應(yīng)用中的頁面顯示速度
2. 如何影響性能
繪制影響Android性能的實(shí)質(zhì):頁面的繪制時(shí)間
1個(gè)頁面通過遞歸 完成測(cè)量 & 繪制過程
3. 優(yōu)化思路
主要優(yōu)化方向是:
- 降低
View.onDraw()的復(fù)雜度 - 避免過度繪制
(Overdraw)
4. 具體優(yōu)化方案
- 具體如下

- 下面,我將詳細(xì)分析每種優(yōu)化方案
4.1. 降低View.onDraw()的復(fù)雜度
4.1.1 onDraw()中不要?jiǎng)?chuàng)建新的局部對(duì)象

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

4.2 避免過度繪制(Overdraw)
4.2.1 過度繪制的簡(jiǎn)介

4.2.2 過度繪制的表現(xiàn)形式
過度繪制 會(huì)導(dǎo)致屏幕顯示的色塊不同,具體如下

附:示例說明

4.2.3 過度繪制的優(yōu)化原則
很多 過度繪制是難以避免的,如 上述實(shí)例的 文字 & 背景導(dǎo)致的過度繪制,只能盡可能避免過度繪制:
- 盡可能地控制 過度繪制的次數(shù) =
2次(綠色)以下,藍(lán)色最理想 - 盡可能避免 過度繪制的粉色 & 紅色情況
- 不允許 3 次以上的過度繪制(淡紅色)面積 超過 屏幕大小的 1/4
4.2.4 優(yōu)化方案
- 移除默認(rèn)的
Window背景 - 移除 控件中不必要的背景
- 減少布局文件的層級(jí)(嵌套)
- 自定義控件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個(gè)常見場(chǎng)景:
- 場(chǎng)景1:
ListView與Item
列表頁(ListView)與 其內(nèi)子控件(Item)的背景相同 = 白色,故可移除子控件(Item)布局中的背景

- 場(chǎng)景2:
ViewPager與Fragment
對(duì)于1個(gè)ViewPager+ 多個(gè)Fragment組成的首頁界面,若每個(gè)Fragment都設(shè)有背景色,即 ViewPager 則無必要設(shè)置,可移除

關(guān)于更多場(chǎng)景,可使用工具 Hierarchy View 查看,具體請(qǐng)看文章: 過渡繪制的使用工具:Hierarchy View
優(yōu)化方案3:減少布局文件的層級(jí)(減少不必要的嵌套)
- 原理:減少不必要的嵌套 ->> UI層級(jí)少 ->> 過度繪制的可能性低
- 優(yōu)化方式:使用布局標(biāo)簽
<merge>& 合適選擇布局類型
具體請(qǐng)看文章:Android性能優(yōu)化:這是一份詳細(xì)的布局優(yōu)化 指南(含<include>、<Viewstub>、<merge>)
優(yōu)化方案4:自定義控件View優(yōu)化:使用 clipRect() 、 quickReject()
-
clipRect()- 作用:給 Canvas 設(shè)置一個(gè)裁剪區(qū)域,只有在該區(qū)域內(nèi)才會(huì)被繪制,區(qū)域之外的都不繪制
- 實(shí)例說明:
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()- 作用:判斷和某個(gè)矩形相交
- 具體措施:若判斷與矩形相交,則可跳過相交的區(qū)域,從而減少過度繪制
4.3 其他優(yōu)化方案

總結(jié)

至此,關(guān)于繪制優(yōu)化的方案講解完畢。
5. 布局調(diào)優(yōu)工具
- 背景
盡管已經(jīng)注意到上述的優(yōu)化策略,但實(shí)際開發(fā)中難免還是會(huì)出現(xiàn)布局性能的問題 - 解決方案
使用 布局調(diào)優(yōu)工具
此處主要介紹 常用的:
hierarchy viewer、Profile GPU Rendering、Systrace
5.1 Hierarchy Viewer
簡(jiǎn)介
Android Studio提供的UI性能檢測(cè)工具。作用
可視化獲得UI布局設(shè)計(jì)結(jié)構(gòu) & 各種屬性信息,幫助我們優(yōu)化布局設(shè)計(jì)
即 :方便查看
Activity布局,各個(gè)View的屬性、布局測(cè)量-布局-繪制的時(shí)間
5.2 Profile GPU Rendering
簡(jiǎn)介
一個(gè) 圖形監(jiān)測(cè)工具作用
渲染、繪制性能追蹤
能實(shí)時(shí)反應(yīng)當(dāng)前繪制的耗時(shí)
- 具體使用
橫軸 = 時(shí)間、縱軸 = 每幀的耗時(shí);隨著時(shí)間推移,從左到右的刷新呈現(xiàn)
提供一個(gè)標(biāo)準(zhǔn)的耗時(shí),如果高于標(biāo)準(zhǔn)耗時(shí),就表示當(dāng)前這一幀丟失

更詳細(xì)使用請(qǐng)看: Profile GPU Rendering 使用指南
5.3 Systrace
- 簡(jiǎn)介
Android 4.1以上版本提供的性能數(shù)據(jù)采樣 & 分析工具 - 作用
檢測(cè)Android系統(tǒng)各個(gè)組件隨著時(shí)間的運(yùn)行狀態(tài) & 提供解決方案
- 收集 等運(yùn)行信息,從而幫助開發(fā)者更直觀地分析系統(tǒng)瓶頸,改進(jìn)性能
檢測(cè)范圍包括:Android關(guān)鍵子系統(tǒng)(如WindowManagerService等Framework部分關(guān)鍵模塊)、服務(wù)、View系統(tǒng)- 功能包括:跟蹤系統(tǒng)的
I/O操作、內(nèi)核工作隊(duì)列、CPU負(fù)載等,在 UI 顯示性能分析上提供很好的數(shù)據(jù),特別是在動(dòng)畫播放不流暢、渲染卡等問題上
- 具體使用
Systrace 使用指南
6. 總結(jié)
- 本文主要講解
Android性能優(yōu)化中的 繪制優(yōu)化

- 下面我將繼續(xù)深入講解
Android中的性能優(yōu)化 ,感興趣的同學(xué)可以繼續(xù)關(guān)注本人運(yùn)營(yíng)的Wechat Public Account: - 我想給你們介紹一個(gè)與眾不同的Android微信公眾號(hào)(福利回贈(zèng))
- 我想邀請(qǐng)您和我一起寫Android(福利回贈(zèng))
請(qǐng)點(diǎn)贊!因?yàn)槟愕墓膭?lì)是我寫作的最大動(dòng)力!
相關(guān)文章閱讀
Android開發(fā):最全面、最易懂的Android屏幕適配解決方案
Android事件分發(fā)機(jī)制詳解:史上最全面、最易懂
Android開發(fā):史上最全的Android消息推送解決方案
Android開發(fā):最全面、最易懂的Webview詳解
Android開發(fā):JSON簡(jiǎn)介及最全面解析方法!
Android四大組件:Service服務(wù)史上最全面解析
Android四大組件:BroadcastReceiver史上最全面解析
歡迎關(guān)注Carson_Ho的簡(jiǎn)書!
不定期分享關(guān)于安卓開發(fā)的干貨,追求短、平、快,但卻不缺深度。
