【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )
文章目錄
- 一、 背景設置產生的過度繪制
- 二、 Android 系統的渲染優化
- 1. 透明組件數據傳遞
- 2. GPU 存儲機制
- 3. Android 7.0 之后的優化機制
- 三、 自定義布局渲染優化
一、 背景設置產生的過度繪制
1. 背景設置產生的過度繪制 :
① 組件背景 : 每個組件每設置一次背景 , 該組件的區域就會增加一層繪制 , 如 LinearLayout 線性布局設置背景顏色 , TextView 設置背景顏色 , 都會增加該組件區域內的過渡繪制 ;
② 布局背景 : 布局文件總的背景 , 會增加一次 GPU 繪制 ;
③ 主題背景 : Activity 界面的主題背景 , 會增加一次 GPU 繪制 ;
2. 組件背景設置策略 : 不要隨便為組件添加背景 , 添加一次背景 , 就增加一次 GPU 繪制 ;
不要隨意給布局中的 UI 組件設置背景 , 能不設置背景的就不設置背景 , 如 ImageView 組件 , 設置一張圖片 , 會增加一次繪制 , 如果再給該 ImageView 組件設置背景顏色 , 那么又會增加一次繪制 , 那么該 ImageView 組件肯定過渡繪制了 ;
二、 Android 系統的渲染優化
在 【Android 性能優化】布局渲染優化 ( CPU 與 GPU 架構分析 | 安卓布局顯示流程 | 視覺與幀率分析 | 渲染超時卡頓分析 | 渲染過程與優化 ) 博客中分析了圖像渲染的 16 毫秒過程中
- CPU 渲染
- CPU 傳遞數據到 GPU
- GPU 渲染
是三大耗時操作 , 上述分析的背景過渡繪制 , 是從減少 GPU 渲染時間角度出發 , 降低圖像渲染時間 ;
CPU 傳遞數據給 GPU 非常耗時 ;
下面分析是從 降低 CPU 傳遞數據到 GPU 時間 角度出發 , 進行的優化 , 這部分優化是由 Android 系統完成的 ;
1. 透明組件數據傳遞
Android 系統做了如下自動優化操作 , 當組件的背景是透明的 , 那么 CPU 將該組件轉為多維向量圖片 ( 多邊形和紋理組成 ) 時發現該組件是透明的 , 該組件的圖像信息就不會傳遞給 GPU 進行渲染 , 從而減少了 CPU 向 GPU 傳遞的數據大小 ; 之前講到過 , CPU 向 GPU 傳遞數據也是一個非常耗時的操作 , 因此該優化 , 也降低了組件渲染的時間 ;
透明組件擺放處理 : CPU 不傳遞這些組件到 GPU 中 , 但是在布局中仍然正常擺放 ;
2. GPU 存儲機制
1. GPU 存儲紋理機制 : GPU 中的顯存可以存儲紋理資源 , 即多維向量圖形資源 , 在渲染時 , 可以直接使用該存儲的資源 , 不用每次都讓 CPU 傳遞數據過來 ;
2. CPU 傳遞主題資源給 GPU 機制 : 傳遞主題資源是一次性傳遞 , 主題中的 背景 , 顏色 , 圖片 ( Bitmap , Drawable ) 等資源都打包存儲在了多維向量圖形 ( 多邊形 和 紋理 ) 中 , 傳遞給 GPU 進行渲染 , GPU 每次進行渲染時直接從存儲區域取出這些資源 , 進行渲染 , 不再依賴 CPU 實時傳遞 ;
這種變化較少的資源 , 適合一次性加載 , 應用或界面的主題資源基本不會改變 ;
3. 普通的 UI 組件資源 : 如果是普通的 UI 組件 , 那么就不能只加載一次了 , 需要每次渲染時 , CPU 都要將組件加載到內存 , 并轉成的多維向量圖形 , 最后傳遞給 GPU ;
3. Android 7.0 之后的優化機制
Android 7.0 之后的優化機制 :
① 7.0 系統優化前 : Android 7.0 之前調用 UI 組件的 invalidate 方法 , 組件會回調 onLayout , onMeasure 和 onDraw 方法 ;
② 7.0 系統優化后 : Android 7.0 之后調用 UI 組件的 invalidate 方法 , 組件不會回調 onLayout 和 onMeasure 方法 , 只會調用 onDraw 方法 ;
③ 7.0 系統優化后工作機制 : 在 GPU 中緩存 UI 組件對應的多維向量圖形 ( 紋理 ) , 當該組件位置或顏色等外觀發生變化時 , 就會通知 CPU , 重新進行加載 , 如 onLayout 擺放 , onMeasure 測量 , 并轉為多維向量圖 ( 紋理 ) , 傳遞給 GPU 進行渲染 ; 如果沒有發生變化 , 調用 invalidate 方法 , 只會在 GPU 中重新渲染 ; 不會重新 擺放 ( onLayout ) 與 測量 ( onMeasure ) ;
三、 自定義布局渲染優化
1. 自定義組件過度繪制問題描述 : 自定義控件 , 在自定義的 onDraw 方法中 , 繪制多張圖片 , 如果圖片之間產生重疊 , 重疊繪制的部分就出現了過度繪制 ;
2. 自定義組件繪制原則 :
① 兩張圖片 : 圖片 AAA 和 圖片 BBB ;
② 圖片覆蓋 : 當圖片 AAA 被圖片 BBB 覆蓋時 , 只繪制圖片 AAA 顯示的部分區域 , 圖片 AAA 被圖片 BBB 覆蓋的部分不再繪制 ;
③ 圖片 AAA 只繪制沒有被覆蓋的部分 : 只在圖片 AAA 顯示的區域繪制圖片 AAA 的區域 , 如下圖黃色框中的區域 ;
3. 實現上述圖片 AAA 在 Canvas 畫布上繪制部分圖片方式 :
① 完整畫布 : onDraw 函數中的 Canvas canvas 參數是完整的畫布 ;
② 取出圖片 AAA 繪制部分的 Canvas 畫布 : 這部分畫布就是上圖中 , 被黃色框框起來的畫布 , 傳入的四個參數是黃色矩形框的左上右下參數 , 注意剪切之前先保存畫布 ;
// 剪切畫布前 , 先保存畫布 , 之后還要恢復回去 canvas.save(); // 剪切畫布 canvas.clipRect(left, top, right, bottom);③ 在剪切后的畫布中繪制圖片 AAA : 在剪切后的畫布中 , 繪制圖片 AAA , 注意繪制完成后 , 恢復畫布 ;
// 在剪切后的畫布中 , 繪制圖片 A canvas.drawBitmap(...); // 繪制完畢后 , 恢復畫布 canvas.restore();④ 繪制效果 : 上述代碼的繪制效果大概就是繪制了部分圖片 AAA , 下圖中的下面的部分圖片 AAA 展示 ;
3. clipRect 函數原型 : 剪切畫布 , 獲取 Canvas 完整畫布的子畫布 , 傳入左 , 上 , 右 , 下 , 四個值 , 將畫布剪切出來 ;
public boolean clipRect(float left, float top, float right, float bottom) {return nClipRect(mNativeCanvasWrapper, left, top, right, bottom,Region.Op.INTERSECT.nativeInt);}總結
以上是生活随笔為你收集整理的【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 性能优化】布局渲染优化
- 下一篇: 【Android 性能优化】布局渲染优化