作者:陳誠 團隊:騰訊移動品質中心TMQ
1、從android卡頓說起
通常我們可以從各種管道聽到使用者回報app卡頓,究竟是什麼使用者覺得卡頓呢?因為大多數手機的螢幕重新整理頻率是60hz,如果在1000/60=16.67ms内沒有辦法把這一幀的任務執行完畢,就會發生丢幀的現象。丢幀越多,使用者感受到的卡頓情況就越嚴重。

是以,可以看出更新每一幀耗時至關重要,說道每一幀圖像的更新過程不得不提到GPU和CPU。CPU負責包括Measure,Layout,Record,Execute的計算操作,GPU負責Rasterization(栅格化)操作。例如顯示圖檔的時候,需要先經過CPU的計算加載到記憶體中,然後傳遞給GPU進行渲染。一旦GPU或者CPU的工作超過了規定事件,就會出現app卡頓現象。比如:
(1)GPU耗時導緻卡頓原因:通常與畫面的渲染有關,比如界面存在嚴重的過度渲染,渲染高清大圖等,與UI View的渲染方法如draw()、onDraw()、dispatchDraw()等關聯。
(2)CPU的耗時導緻卡頓原因:主要是由于UI線程有耗時較久的操作,比如處理大圖檔、進行耗時的IPC通信等,自然會拖長UI線程處理的時間。UI線程通常會運作以下方法: 渲染相關方法; UI布局相關方法:
onMeasure(),onLayout();
Handler: handleMessage();
post(Runnable);
Activity相關方法, 如:
onCreate(),onResume(),onStar(),onStop()等。
2、再談過度渲染
Overdraw(過度渲染)是指的手機螢幕上的一個像素點在一幀更新時間内被繪制了多次,我們就認為試過繪制了。顯然過渡繪制發生時,在UI層次中處于被遮擋的繪制是不可見的,也是對資源的浪費。用一個簡單的例子,好比我們刷牆,刷了一層又一層,最終能看到的牆還是最後一次刷上去的樣子。
既然過度渲染問題嚴重,那麼如何發現是否有過度渲染存在呢?google在安卓4.4系統中開發了檢視過度渲染計數的入口,在開發者選項中,打開GPU調試,選擇過度渲染計數,螢幕左下方可以看到目前視窗過度渲染計數。如手機管家7.0首頁過度渲染計數。
具體的數值代表的意義為:
藍色:1倍過度繪制,1.X;
綠色:2倍過度繪制,2.X;
淡紅色:3倍過度繪制,3.X;
紅色:4倍或以上過度繪制, 4.X。
既然能夠通過系統設定知道過度渲染次數,測試時候就讀取該值,填寫報告就完了啊,為何要自動化呢?因為在對app進行系統的測試時,會發現頁面非常多,如管家一二級頁面就多大20多個,且內建包,灰階包,正式包,回歸包都要進行一次測試,是以進行自動化過度渲染計數讀取是有必要的。
1、擷取頁面過度渲染計數
(1)HOOK系統方法,讀取過度渲染計數。
通過檢視安卓4.4的源碼,可以知道在Framework/base/core/Java/android/view/
HardwareRender.java中有一個叫做GLRenderer的内部類,該類還有一個方法如下:
我們能夠hook該方法,抓取入參overdraw并列印到日志,就是我們需要的過度渲染計數。
【難點】
1)如何hook内部類的方法:在外部類和内部類之間添加 $符号定位内部類;
2)如何構造一個隐藏的參數類型,如上述HardWareCanvas:直接使用包名加類名定位該類型。
通過hook的方法輸出的過度渲染計數來源于系統調用API,是以什麼時候能拿到這個值不受人為控制,使用者隻能等待系統日志輸出,這也是hook技術的通病,為此我們引入第二種方法。
(2)反射系統過度渲染計數的類,輸出過度渲染計數。
系統在螢幕中繪制過度渲染計數時,是通過drawText繪制到螢幕上(上述(1)方法的源碼截圖看出),是以找到調用繪制方法的類,就可以得到過度渲染計數,同樣在HardwareRenderer.java代碼中debugOverdraw調用了繪制的方法,該方法也是過度渲染計數擷取的方法。
注:以上方法都是通過系統函數擷取過度渲染計數,是以測試時,必須打開設定中的過度渲染計數。
2、實作自動化測試
(1)在什麼時候讀取頁面overdrawcounter值?
頁面從建立到銷毀,什麼時候頁面才是最繪制最穩定的時候呢?我們假設頁面上有需要下載下傳的資源,需要耗時才能擷取的資源等,是以隻有在頁面消失前一刻,我們才認為此時頁面相對繪制最完整。是以跟進安卓生命周期,我們在onPause()時來讀取過度渲染計數。
(2)如何實作自動化呢?
因為在調用onPause()時候會自動讀取過度渲染值,是以我們要做的自動化僅僅是如何在被測頁面之間切換,搜集各個頁面的過度渲染值,輸出報告,是以流程可以歸納為:
1、整個測試方案在手機管家7.0中運作起來,對內建包,灰階包,正式包的一二級頁面進行了過度渲染測試,優化後管家正式包一二級頁面平均過度渲染計數為2.4X,小于管家标準3.0X。
報告樣例為:
2、對手機管家22個基礎頁面監控,到正式版釋出時全部頁面過度渲染計數都小于3.0X。下圖為管家部分頁面優化前後對比。
管家主界面:
體檢優化界面:
個人中心頁面:
3、問題頁面優化前後過度渲染計數對比
擷取更多測試幹貨,關注騰訊移動品質中心TMQ微信公衆号。