流暢度測試簡單的來講就是Android頁面繪製。Android系統每秒60hz,也就是大約每16ms刷新一次界面。可是在咱們使用APP過程當中,常常會看到頁面有卡頓,或者說丟幀的現象。也就是說可能此刻兩個頁面繪製的時間差超過0.1S(人眼視覺殘留0.1S)。總的來講,就是頁面oop
原理分析測試
在肯定衡量指標以前,先來講Android的UI更新機制。動畫
在Android版本更新過程當中,發如今Jelly Bean中Google加入了一個Project Butter,用來解決嚴重影響Android口碑的問題之一「UI流暢性差」的問題。而Project Butter中主要引入了三個核心元素:VSYNC(垂直同步)、Triple Buffer和Choreographer。對象
VSync是Vertical Synchronization(垂直同步)的縮寫,是一種在PC上很早就普遍使用的技術,能夠簡單的把它認爲是一種定時中斷。而在Android 4.1(JB)中已經開始引入VSync機制。CPU和GPU的處理時間都少於一個VSync的間隔,即16.6ms。若是每一個間隔都有繪製的狀況下,當前的FPS即爲60幀。事件
VSync機制就像是播放動畫片(60幀/s)。每次都會播放畫面,有的時候有人偷懶了,機器壞了,就會出現播放速度下降的情況。咱們把這個播放速度叫作流暢度。ip
從FPS&丟幀到流暢度文檔
實際上在不少Android的App中,不多有須要不斷地去繪製的場景,不少時候頁面都是靜態的。也就是會出現這樣的情況,雖然1s中VSync的60個Loop不是每一個都在作繪製的工做,FPS會比較低,但並不表明這個時候程序不流暢(如我將App放着不動,實測FPS爲1)。因此FPS較低並不能表明當前App在UI上界面不流暢,而1s內VSync這個Loop運行了多少次更加能說明當前App的流暢程度。因此,下面這2個指標比FPS更能表明當前的App是否處於流暢的狀態。一樣這2個指標更加可以量化App卡頓的程度:get
1)丟幀(SF: Skipped Frame):如上圖2所示狀況應該在16.6ms完成工做卻因各類緣由沒作完,佔了後n個16.6ms的時間,至關於丟了n幀。input
2)流暢度(SM: SMoothness):和丟幀相對,在VSync機制中1s內Loop運行的次數。animation
和丟幀相對1s內有60個Loop由於某幾回工做時間超過了16.6ms(丟幀),這樣Loop就沒法運行60次(理論最大值)。
當流暢度越小的時候說明當前程序越卡頓。
如何獲得流暢度(SM: SMoothness)
接着上面的結論,若是在這樣的機制下每次Loop運行以前進行通知,記個數就行了。
很幸運咱們在新的Android的那一套機制中找到了一個畫圖的打雜工Choreographer這個對象。根據Google的官方API文檔描述中,它是用來協調animations、input以及drawing時序的,而且每一個Loop共用一個Choreographer對象。
結論
經過如上原理分析能夠得出結論:
1) Android 4.1引入了VSync機制後,能夠經過其Loop來了解當前App最高繪製能力。
固定每隔16.6ms執行一次(這個值是一個靜態變量,會根據系統版本不一樣而採用不一樣的值,目前測試版本是16.6ms這樣最高的刷新的幀率就控制在60FPS之內);
若是沒有以上事件的時候一樣也會運行這樣一個Loop;
這個Loop在1s以內運行了多少次,便可以表示當前App繪製的最高的能力,也就是Android App卡頓的程度;
另外,在一次Loop時若是執行時間超過了16.6ms,那麼用多於16.6ms的時間除以16.6ms,便是當前App的丟幀(SF: Skipped Frame)。
2) 能夠在Choreographer的回調FrameCallback中,按秒計數表示當前App的流暢程度,即流暢度SM(SMoothness)。
採用這樣方式就能夠在App內部觀測當前App的流暢度了。而且在丟幀的地方打印traceView,就能夠知道丟幀的大概緣由,大概位置。定位代碼問題。