Android的渲染機制

1.前言

(1)岛抄、 CPU: 中央處理器,它集成了運算,緩沖,控制等單元,包括繪圖功能.CPU將對象處理為多維圖形,紋理(Bitmaps夫椭、Drawables等都是一起打包到統(tǒng)一的紋理).

(2)蹭秋、GPU:一個類似于CPU的專門用來處理Graphics的處理器, 作用用來幫助加快格柵化操作,當然,也有相應的緩存數據(例如緩存已經光柵化過的bitmap等)機制仁讨。

(3)洞豁、 OpenGL ES是手持嵌入式設備的3DAPI,跨平臺的、功能完善的2D和3D圖形應用程序接口API,有一套固定渲染管線流程. 附相關OpenGL渲染流程資料锐墙、OpenGL ES使用

(4)长酗、 DisplayListAndroid把XML布局文件轉換成GPU能夠識別并繪制的對象夺脾。這個操作是在DisplayList的幫助下完成的咧叭。DisplayList持有所有將要交給GPU繪制到屏幕上的數據信息。

(5)吉挣、 格柵化 是 將圖片等矢量資源,轉化為一格格像素點的像素圖,顯示到屏幕上睬魂。

(6)、 垂直同步VSYNC:讓顯卡的運算和顯示器刷新率一致以穩(wěn)定輸出的畫面質量商佛。它告知GPU在載入新幀之前良姆,要等待屏幕繪制完成前一幀歇盼。下面的三張圖分別是GPU和硬件同步所發(fā)生的情況,Refresh Rate:屏幕一秒內刷新屏幕的次數,由硬件決定,例如60Hz.而Frame Rate:GPU一秒繪制操作的幀數,單位是30fps,正常情況過程圖如下.

圖一

2.渲染機制介紹

(1)渲染流程線

UI對象—->CPU處理為多維圖形,紋理 —–通過OpeGL ES接口調用GPU—-> GPU對圖進行光柵化(Frame Rate ) —->硬件時鐘(Refresh Rate)—-垂直同步—->投射到屏幕

圖二

(2)渲染時間線

Android系統(tǒng)每隔16ms發(fā)出VSYNC信號(1000ms/60=16.66ms)伯复,觸發(fā)對UI進行渲染啸如, 如果每次渲染都成功氮惯,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現(xiàn)60fps帘不,這意味著計算渲染的大多數操作都必須在16ms內完成寞焙。

I辽狈、正常情況

圖三

II刮萌、渲染超時,計算渲染時間超過16ms

當這一幀畫面渲染時間超過16ms的時候,垂直同步機制會讓顯示器硬件 等待GPU完成柵格化渲染操作,
這樣會讓這一幀畫面,多停留了16ms,甚至更多.這樣就這造成了 用戶看起來 畫面停頓.

當GPU渲染速度過慢,就會導致如下情況,某些幀顯示的畫面內容就會與上一幀的畫面相同

圖四

3.渲染時會出現(xiàn)的問題

(1) GPU過度繪制

GPU的繪制過程,就跟刷墻一樣,一層層的進行,16ms刷一次.這樣就會造成,圖層覆蓋的現(xiàn)象,即無用的圖層還被繪制在底層,造成不必要的浪費.

圖五

(2)過度繪制查看工具

在手機端的開發(fā)者選項里,有OverDraw監(jiān)測工具,調試GPU過度繪制工具,
其中顏色代表渲染的圖層情況,分別代表1層,2層,3層,4層覆蓋.

圖六

手機的Monitor GPU Rendering

圖六

(3)計算渲染的耗時

任何時候View中的繪制內容發(fā)生變化時畜侦,都會重新執(zhí)行創(chuàng)建DisplayList旋膳,渲染DisplayList验懊,更新到屏幕上等一 系列操作义图。這個流程的表現(xiàn)性能取決于你的View的復雜程度碱工,View的狀態(tài)變化以及渲染管道的執(zhí)行性能。

舉個例子,當View的大小發(fā)生改變,DisplayList就會重新創(chuàng)建,然后再渲染,而當View發(fā)生位移,則DisplayList不會重新創(chuàng)建,而是執(zhí)行重新渲染的操作酗昼。

當你的View過于復雜,操作又過于復雜,就會計算渲染時間超過16ms,產生卡頓問題麻削。

(4)渲染耗時呈現(xiàn)工具

工具中,不同手機呈現(xiàn)方式可能會有差別.分別關于StatusBar,NavBar叠荠,激活的程序Activity區(qū)域的GPU Rending信息俺祠。激活的程序Activity區(qū)域的GPU Rending信息。

界面上會滾動顯示垂直的柱狀圖來表示每幀畫面所需要渲染的時間蜘渣,柱狀圖越高表示花費的渲染時間越長。

中間有一根綠色的橫線拾碌,代表16ms街望,我們需要確保每一幀花費的總時間都低于這條橫線,這樣才能夠避免出現(xiàn)卡頓的問題防症。

圖八

每一條柱狀線都包含三部分,
藍色代表測量繪制Display List的時間奈嘿,
紅色代表OpenGL渲染Display List所需要的時間裙犹,
黃色代表CPU等待GPU處理的時間衔憨。

圖九

4. 如何促進優(yōu)化

有人會說這些小地方,不值得優(yōu)化.但是當你用的是低配機器,內存到飽和,CPU運算到達飽和,就像一個界面要做很多交互,繪制,加載圖片,請求網絡.后,一個小問題就會導致頁面卡頓,OOM,項目崩潰.

(1)Android系統(tǒng)已經對它優(yōu)化

在Android里面那些由主題所提供的資源,例如Bitmaps平项,Drawables都是一起打包到統(tǒng)一的Texture紋理當中赫舒,然后再傳遞到 GPU里面悍及,這意味著每次你需要使用這些資源的時候,都是直接從紋理里面進行獲取渲染的接癌。

(2)要做的優(yōu)化

扁平化處理,防止過度繪制OverDraw

(3)每一個layout的最外層父容器 是否需要?

圖十

(4)布局層級優(yōu)化

進行檢測時,可能會讓多種檢測工具沖突,用Android Device Monitor的時候,最好關閉相關手機上的開發(fā)者檢測工具開關.
查看自己的布局心赶,深的層級,是否可以做優(yōu)化.
渲染比較耗時(顏色就能看出來),想辦法能否減少層級以及優(yōu)化每一個View的渲染時間.

(5)Hierarchy Viewer工具**

他是查看耗時情況,和布局樹的深度的工具.

這里寫圖片描述

(6)圖片選擇

Android的界面能用png最好是用png了,因為32位的png顏色過渡平滑且支持透明缺猛。jpg是像素化壓縮過的圖片缨叫,質量已經下降了,再拿來做9path的按鈕和平鋪拉伸的控件必然慘不忍睹荔燎,要盡量避免耻姥。

(7)清理不必要的背景

圖十一

(8)當背景無法避免,盡量用Color.TRANSPARENT

因為透明色Color.TRANSPARENT是不會被渲染的,他是透明的.


//優(yōu)化前
//優(yōu)化前: 當圖片不為空,ImageView加載圖片,然后統(tǒng)一設置背景
Bean bean=list.get(i);
 if (bean.img == 0) {
            Picasso.with(getContext()).load(bean.img).into(holder.imageView);
        }
        chat_author_avatar.setBackgroundColor(bean.backPic);

//優(yōu)化后
//優(yōu)化后:當圖片不為空,ImageView加載圖片,并設置背景為TRANSPARENT;
//當圖片為空,ImageView加載TRANSPARENT,然后設置背景為無照片背景
Bean bean=list.get(i);
 if (bean.img == 0) {
            Picasso.with(getContext()).load(android.R.color.transparent).into(holder.imageView);
            holder.imageView.setBackgroundColor(bean.backPic);
        } else {
            Picasso.with(getContext()).load(bean.img).into(holder.imageView);
            holder.imageView.setBackgroundColor(Color.TRANSPARENT);
        }

圖十二

(9)優(yōu)化自定義View的計算

View中的方法OnMeasure,OnLayout,OnDraw.在我們自定義View起到了決定作用,我們要學會研究其中的優(yōu)化方法.

學會裁剪掉View的覆蓋部分,增加cpu的計算量,來優(yōu)化GPU的渲染


  /**
     * Intersect the current clip with the specified rectangle, which is
     * expressed in local coordinates.
     *
     * @param left   The left side of the rectangle to intersect with the
     *               current clip
     * @param top    The top of the rectangle to intersect with the current clip
     * @param right  The right side of the rectangle to intersect with the
     *               current clip
     * @param bottom The bottom of the rectangle to intersect with the current
     *               clip
     * @return       true if the resulting clip is non-empty
     */
    public boolean clipRect(float left, float top, float right, float bottom) {
        return native_clipRect(mNativeCanvasWrapper, left, top, right, bottom,
                Region.Op.INTERSECT.nativeInt);
    }


5.總結

性能優(yōu)化其實不僅僅是一種技術,而是一種思想,你只聽過它的高大上,卻不知道它其實就是各個細節(jié)處的深入研究和處理.
當然,有的時候也需要自己進行權衡效果和性能,根據需求進行選擇.

所以在平時的開發(fā)過程中,養(yǎng)成良好的思考習慣,是第一步~

代碼的思想:
(1)你的代碼是不是多余?
(2)你的對象有沒有必要在循環(huán)中創(chuàng)建?
(3)你的計算方法是不是最優(yōu)?

畫界面的考慮:
(1)布局是否有背景?
(2)是否可以刪掉多余的布局?
(3)自定義View是否進行了裁剪處理?
(4)布局是否扁平化,移除非必需的UI組?

最后,最后加油吧!騷年,你絕對是一個有逼格的程序猿K芩场!!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子锉走,更是在濱河造成了極大的恐慌梁厉,老刑警劉巖庇麦,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件航棱,死亡現(xiàn)場離奇詭異,居然都是意外死亡观蓄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門茵肃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胚膊,“玉大人喻犁,你說我怎么就攤上這事碌廓〖涂妫” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵叁巨,是天一觀的道長狡蝶。 經常有香客問我奏瞬,道長珍昨,這世上最難降的妖魔是什么兄春? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮躬贡,結果婚禮上,老公的妹妹穿的比我還像新娘咳短。我一直安慰自己,他們只是感情好缀台,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布脯丝。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裕膀,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天蛹含,我揣著相機與錄音浦箱,去河邊找鬼竖幔。 笑死馋评,一個胖子當著我的面吹牛糊渊,可吹牛的內容都是我干的。 我是一名探鬼主播主到,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贸呢!你這毒婦竟也來了镰烧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤楞陷,失蹤者是張志新(化名)和其女友劉穎怔鳖,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體固蛾,經...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡结执,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了艾凯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片献幔。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖趾诗,靈堂內的尸體忽然破棺而出蜡感,到底是詐尸還是另有隱情,我是刑警寧澤恃泪,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布郑兴,位于F島的核電站,受9級特大地震影響贝乎,放射性物質發(fā)生泄漏情连。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一览效、第九天 我趴在偏房一處隱蔽的房頂上張望却舀。 院中可真熱鬧虫几,春花似錦、人聲如沸挽拔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篱昔。三九已至每强,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間州刽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工浪箭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留穗椅,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓奶栖,卻偏偏與公主長得像匹表,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宣鄙,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內容