前言:
流暢度,是頁(yè)面在滑動(dòng)、渲染等過(guò)程中的體驗(yàn)。Android系統(tǒng)要求每一幀都要在 16ms 內(nèi)繪制完成,平滑的完成一幀意味著任何特殊的幀需要執(zhí)行所有的渲染代碼(包括 framework 發(fā)送給 GPU 和 CPU 繪制到緩沖區(qū)的命令)都要在 16ms 內(nèi)完成,保持流暢的體驗(yàn)。如果沒(méi)有在期間完成渲染秒就會(huì)發(fā)生掉幀。掉幀是用戶體驗(yàn)中一個(gè)非常核心的問(wèn)題。丟棄了當(dāng)前幀,并且之后不能夠延續(xù)之前的幀率,這種不連續(xù)的間隔會(huì)容易會(huì)引起用戶的注意,也就是我們常說(shuō)的卡頓、不流暢。
導(dǎo)致掉幀的原因會(huì)有很多,這里只列出以下幾點(diǎn):
?花了非常多時(shí)間重新繪制界面中的大部分東西,這樣非常浪費(fèi)CPU周期;
?過(guò)度繪制嚴(yán)重,在繪制用戶看不到的對(duì)象上花費(fèi)了太多的時(shí)間
?有一大堆動(dòng)畫(huà)重復(fù)了一遍又一遍,消耗 CPU 、 GPU 資源
?頻繁的觸發(fā)垃圾回收。
追蹤性能方法
Hierarchy View
Overdraw
Rendering (渲染性能)
Hierarchy View
Hierarchy View 在Android SDK里自帶,常用來(lái)查看界面的視圖結(jié)構(gòu)是否過(guò)于復(fù)雜,用于了解哪些視圖過(guò)度繪制。還給出關(guān)于測(cè)量、布局、繪制的性能。

分析示例:如果red dot在一個(gè)葉子節(jié)點(diǎn)或者一個(gè)只有幾個(gè)子節(jié)點(diǎn)的ViewGroup上,可能會(huì)存在一些問(wèn)題。APP整體表現(xiàn)可能不壞,但是你要意識(shí)到那個(gè)節(jié)點(diǎn)為什么是紅色的!可以使用Systrace或者 TraceView做進(jìn)一步的分析。
如果ViewGroup的Measure 是紅色的,要分析一下它的子節(jié)點(diǎn)。
如果View存在黃色甚至紅色dot,可能在手機(jī)上的運(yùn)行效率并不慢,可能是由于view的數(shù)目過(guò)多造成的??梢允褂肧ystrace或者 TraceView做進(jìn)一步的分析。
如果一個(gè)層級(jí)結(jié)構(gòu)的根節(jié)點(diǎn)measure dot是紅色的,layout dot是紅色的,draw dot是黃色的,這是一種非常典型的情況,因?yàn)樗撬泄?jié)點(diǎn)的根節(jié)點(diǎn)。
如果一個(gè)有20+ view的層級(jí)結(jié)構(gòu)中,一個(gè)葉子節(jié)點(diǎn)draw dot是紅色的,那肯定是問(wèn)題,檢查一下它的onDraw方法。
官方介紹
https://developer.android.com/studio/profile/hierarchy-viewer-walkthru.html
Overdraw
Overdraw表示某些組件在屏幕上的一個(gè)像素點(diǎn)的繪制次數(shù)超過(guò) 1 次??梢酝ㄟ^(guò)開(kāi)發(fā)者選項(xiàng)里打開(kāi) “ 調(diào)試 GPU 過(guò)度繪制獲得相關(guān)信息。

用顏色來(lái)區(qū)別過(guò)度繪制程度:

①?zèng)]顏色:沒(méi)有過(guò)度繪制,顯示應(yīng)用本來(lái)的顏色
②藍(lán)色:1倍過(guò)度繪制
③綠色:2倍過(guò)度繪制
④淺紅色:3倍過(guò)度繪制
⑤深紅色:4倍過(guò)度繪制及以上
導(dǎo)致過(guò)度繪制的原因很多,例如:
①視圖相互重疊的問(wèn)題
|-- 不必要的背景重疊,如上圖官網(wǎng)介紹
②不合理的xml布局對(duì)繪制的影響
|-- 當(dāng)布局文件的節(jié)點(diǎn)樹(shù)的深度越深,XML 中的標(biāo)簽和屬性設(shè)置越多,對(duì)界面的顯示有巨大影響。一個(gè)界面要顯示出來(lái),第一步會(huì)進(jìn)行解析布局,在 requestLayout 之后還要進(jìn)行一系列的 measure 、 layout 、 draw 操作,若布局文件嵌套過(guò)深、擁有的標(biāo)簽屬性過(guò)于臃腫,每一步的執(zhí)行時(shí)間都會(huì)受到影響,而界面的顯示是進(jìn)行完這些操作后才會(huì)顯示的,所以每一步操作的時(shí)間增長(zhǎng),最終顯示的時(shí)間就會(huì)越長(zhǎng)。
官網(wǎng)給出的合理的頁(yè)面過(guò)度繪制情況

渲染性能
渲染性能往往是掉幀的罪魁禍?zhǔn)?,通過(guò)在 Android 設(shè)備的設(shè)置 APP 的開(kāi)發(fā)者選項(xiàng)里打開(kāi) “ GPU 呈現(xiàn)模式分析 ” 選項(xiàng),可以幫我們有效的分析渲染性能。
追蹤渲染性能,通過(guò)向 dumpsys 傳遞“gfxinfo”命令來(lái)跟蹤相關(guān)的信息
1、幀的聚合信息

簡(jiǎn)單的時(shí)間幀信息:
|-- 通過(guò)gfxino獲得,Draw、Process、Excute
$ adb shell dumpsys gfxinfo packageName

1、draw代表的是這一幀繪制 Display List 的時(shí)間。通俗來(lái)說(shuō),就是記錄了需要花費(fèi)多長(zhǎng)時(shí)間在屏幕上更新視圖。用代碼語(yǔ)言來(lái)說(shuō),就是執(zhí)行視圖的 onDraw 方法,創(chuàng)建或更新每一個(gè)視圖的 Display List 的時(shí)間。
2、process代表的是這一幀 OpenGL 渲染 Display List 所需要的時(shí)間。通俗來(lái)說(shuō),就是記錄了執(zhí)行視圖繪制的耗時(shí)。用代碼語(yǔ)言來(lái)說(shuō),就是 Android 用 OpenGL ES 的 API 接口進(jìn)行 2D 渲染 Display List 的時(shí)間。
3、excute代表的是這一幀 CPU 等待 GPU 處理的時(shí)間。通俗來(lái)說(shuō),就是 CPU 等待 GPU 發(fā)出接到命令的回復(fù)的等待時(shí)間。用代碼語(yǔ)言來(lái)說(shuō),就是這是一個(gè)阻塞調(diào)用。
精確的幀時(shí)間信息
通過(guò) gfxinfo framestats獲得
|-- 獲取精確時(shí)間幀數(shù)據(jù):
$ adb shell dumpsys gfxinfo packageName framestats

數(shù)據(jù)分析
已獲取到的第二種數(shù)據(jù)為例,先解釋每列數(shù)據(jù)代表的含義
●標(biāo)志
?窗口布局發(fā)生變化(例如,應(yīng)用的第一幀或在旋轉(zhuǎn)后)
?此外,如果幀的某些值包含無(wú)意義的時(shí)間戳,則也可能跳過(guò)該幀。 例如,如果幀的運(yùn)行速度超過(guò) 60fps,或者如果屏幕上的所有內(nèi)容最終都準(zhǔn)確無(wú)誤,則可能跳過(guò)該幀,這不一定表示應(yīng)用中存在問(wèn)題。
?“標(biāo)志”列帶有“0”的行可以通過(guò)從 FRAME_COMPLETED 列中減去 INTENDED_VSYNC 列計(jì)算得出總幀時(shí)間。
?該列為非零值的行將被忽略,因?yàn)槠鋵?duì)應(yīng)的幀已被確定為偏離正常性能,其布局和繪制時(shí)間預(yù)計(jì)超過(guò) 16 毫秒。 可能出現(xiàn)這種情況有如下幾個(gè)原因:
●INTENDED_VSYNC
?幀的預(yù)期起點(diǎn)。如果此值不同于 VSYNC,則表示 UI 線程中發(fā)生的工作使其無(wú)法及時(shí)響應(yīng)垂直同步信號(hào)。
●VSYNC
?所有垂直同步偵聽(tīng)器中使用的時(shí)間值和幀繪圖(Choreographer 幀回調(diào)、動(dòng)畫(huà)、View.getDrawingTime() 等等)
?如需進(jìn)一步了解 VSYNC 及其對(duì)應(yīng)用產(chǎn)生的影響,請(qǐng)觀看[了解 VSYNC](https://www.youtube.com/watch?v=1iaHxmfZGGc&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=23) 視頻。
●OLDEST_INPUT_EVENT
?輸入隊(duì)列中最早輸入事件的時(shí)間戳或 Long.MAX_VALUE(如果幀沒(méi)有輸入事件)。
?此值主要用于平臺(tái)工作,對(duì)應(yīng)用開(kāi)發(fā)者的作用有限。
●NEWEST_INPUT_EVENT
?輸入隊(duì)列中最新輸入事件的時(shí)間戳或 0(如果幀沒(méi)有輸入事件)。
?此值主要用于平臺(tái)工作,對(duì)應(yīng)用開(kāi)發(fā)者的作用有限。
?但是,可以通過(guò)查看 (FRAME_COMPLETED - NEWEST_INPUT_EVENT) 大致了解應(yīng)用增加的延遲時(shí)間。
●HANDLE_INPUT_START
?將輸入事件分派給應(yīng)用的時(shí)間戳。
?通過(guò)觀察此時(shí)間戳與 ANIMATION_START 之間的時(shí)差,可以測(cè)量應(yīng)用處理輸入事件所花的時(shí)間。
?如果這個(gè)數(shù)字較高(> 2 毫秒),則表明應(yīng)用處理 View.onTouchEvent() 等輸入事件所花的時(shí)間太長(zhǎng),這意味著此工作需要進(jìn)行優(yōu)化或轉(zhuǎn)交給其他線程。 請(qǐng)注意,有些情況下(例如,啟動(dòng)新Activity或類似活動(dòng)的點(diǎn)擊事件),這個(gè)數(shù)字較大是預(yù)料之中并且可以接受的。
●ANIMATION_START
?在 Choreographer 中注冊(cè)的動(dòng)畫(huà)運(yùn)行的時(shí)間戳。
?通過(guò)觀察此時(shí)間戳與 PERFORM_TRANVERSALS_START 之間的時(shí)差,可以確定評(píng)估正在運(yùn)行的所有動(dòng)畫(huà)(ObjectAnimator、ViewPropertyAnimator 和通用轉(zhuǎn)換)所需的時(shí)間。
?如果這個(gè)數(shù)字較高(> 2 毫秒),請(qǐng)檢查您的應(yīng)用是否編寫了任何自定義動(dòng)畫(huà),或檢查 ObjectAnimator 在對(duì)哪些字段設(shè)置動(dòng)畫(huà)并確保它們適用于動(dòng)畫(huà)。
?如需了解有關(guān) Choreographer 的更多信息,請(qǐng)觀看[利弊](https://developers.google.com/events/io/sessions/325418001)視頻。
●PERFORM_TRAVERSALS_START
?如果您從此值中扣除 DRAW_START,則可推斷出完成布局和測(cè)量階段所需的時(shí)間(請(qǐng)注意,在滾動(dòng)或動(dòng)畫(huà)期間,您會(huì)希望此時(shí)間接近于零)。
?如需了解有關(guān)呈現(xiàn)管道的測(cè)量和布局階段的更多信息,請(qǐng)觀看[失效、布局和性能](https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27)視頻。
●DRAW_START
?performTraversals 繪制階段的開(kāi)始時(shí)間。這是記錄任何失效視圖的顯示列表的起點(diǎn)。
?此時(shí)間與 SYNC_START 之間的時(shí)差就是對(duì)樹(shù)中的所有失效視圖調(diào)用 View.draw() 所需的時(shí)間。
?如需了解有關(guān)繪圖模型的詳細(xì)信息,請(qǐng)參閱[硬件加速](https://developer.android.com/guide/topics/graphics/hardware-accel.html#hardware-model)或[失效、布局和性能](https://www.youtube.com/watch?v=we6poP0kw6E&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu&index=27)視頻。
●SYNC_START
?繪制同步階段的開(kāi)始時(shí)間。
?如果此時(shí)間與 ISSUE_DRAW_COMMANDS_START 之間的時(shí)差較大(約 > 0.4 毫秒),則通常表示繪制了大量必須上傳到 GPU 的新位圖。
?如需進(jìn)一步了解同步階段,請(qǐng)觀看 [GPU 呈現(xiàn)模式分析](https://www.youtube.com/watch?v=VzYkVL1n4M8&index=24&list=PLOU2XLYxmsIKEOXh5TwZEv89aofHzNCiu)視頻。
●ISSUE_DRAW_COMMANDS_START
?硬件呈現(xiàn)器開(kāi)始向 GPU 發(fā)出繪圖命令的時(shí)間。
?此時(shí)間與 FRAME_COMPLETED 之間的時(shí)差讓您可以大致了解應(yīng)用生成的 GPU 工作量。 繪制過(guò)度或呈現(xiàn)效果不佳等問(wèn)題都會(huì)在此顯示出來(lái)。
●SWAP_BUFFERS
?調(diào)用 eglSwapBuffers 的時(shí)間,此調(diào)用不屬于平臺(tái)工作,相對(duì)乏味。
●FRAME_COMPLETED
?全部完成!處理此幀所花的總時(shí)間可以通過(guò)執(zhí)行 FRAME_COMPLETED - INTENDED_VSYNC 計(jì)算得出。
由于數(shù)據(jù)塊是 CSV 格式的輸出,因此將其粘貼到所選的電子表格工具或使用腳本進(jìn)行收集和解析非常簡(jiǎn)單。我們可以導(dǎo)入Excel進(jìn)行數(shù)據(jù)處理。

利用公式,進(jìn)一步進(jìn)行計(jì)算結(jié)果,并轉(zhuǎn)換單由納秒 -> 毫秒

最后利用Excel生成簡(jiǎn)單直觀的圖表,統(tǒng)計(jì)平均繪制時(shí)間,以及繪制時(shí)間的占比。如下圖表示大部分幀在16ms一下,表示頁(yè)面流暢度“還可以”
具體哪一幀高了,可到對(duì)應(yīng)的數(shù)據(jù)列表中查看,檢查是哪一步導(dǎo)致的。gfxinfo只提供這種“瀏覽方式”,如果還需要進(jìn)一步詳細(xì)的跟蹤,還是需要System Trace的分析。

控制統(tǒng)計(jì)信息收集
時(shí)間
Framestats 和簡(jiǎn)單的幀計(jì)時(shí)均可在極短的時(shí)間內(nèi)(相當(dāng)于約呈現(xiàn) 2 秒)收集數(shù)據(jù)。 因此需要要精確控制此時(shí)間范圍(例如,將數(shù)據(jù)限制于特定動(dòng)畫(huà)),這里可以通過(guò)reset命令,重置所有計(jì)數(shù)器并匯總收集的統(tǒng)計(jì)信息
|-- 清空最近的信息
$ adb shell dumpsys gfxinfo packageName reset
方法:
通過(guò)命令行,輸出固定的滑動(dòng)坐標(biāo),點(diǎn)到點(diǎn),防止人為操作造成誤差。
$ adb shell input swipe 700 2000 700 200
這里只是看滑動(dòng)過(guò)程中的流暢性,然后收集,用pyhton寫了個(gè)渣腳本臨時(shí)處理excel表格。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author:John Hao
# 測(cè)試流暢度平均繪制時(shí)長(zhǎng)的小腳本
# 功能:滑動(dòng)當(dāng)前頁(yè)面兩次,間隔1秒,收集gfxinfo并制表
# titlename:表示要測(cè)試的模塊和最后文件保存的名字
# |-- 收集gfxinfo framestats詳細(xì)幀數(shù)據(jù)信息
# |-- 用第三方模塊openpyxl處理收集到的excel數(shù)據(jù)
# |-- 輸出2秒內(nèi)的120幀每一幀的繪制時(shí)間
# |-- 輸出平均繪制時(shí)間
import time
import sys
import os
import openpyxl
from openpyxl import Workbook
from openpyxl.styles.colors import Color
from openpyxl.chart import LineChart, Reference, Series
titlelist = [' UI 線程中發(fā)生的工作使其無(wú)法及時(shí)響應(yīng)垂直同步信號(hào)','應(yīng)用處理輸入事件所花的時(shí)間( >2 毫秒表示處理輸入事件時(shí)間長(zhǎng))',
'正在運(yùn)行的所有動(dòng)畫(huà)(ObjectAnimator、ViewPropertyAnimator 和通用轉(zhuǎn)換)所需的時(shí)間',
'完成布局和測(cè)量階段所需的時(shí)間','對(duì)樹(shù)中的所有視圖調(diào)用 View.draw() 所需的時(shí)間',
'約 > 0.4 毫秒表示繪制了大量必須上傳到 GPU 的新位圖','GPU 工作量','處理此幀所花的總時(shí)間','達(dá)標(biāo)線']
subtitlelist = ['IntendedVsync','HandleInputStart','AnimationStart','PerformTraversalsStart',
'DrawStart','SyncStart','IssueDrawCommandsStart','FrameCompleted','Avg']
# 要測(cè)試測(cè)模塊名,最后文件會(huì)以該名稱命名
titlename = "Feed"
print "Starting"
for j in range(1,6):
time.sleep(1)
print "開(kāi)始執(zhí)行第" + str(j) + "遍"
wb = Workbook()
ws = wb.active
ws.title = "data"
valueofwidth = 16
ws.column_dimensions["A"].width = valueofwidth
ws.column_dimensions["B"].width = valueofwidth
ws.column_dimensions["C"].width = valueofwidth
ws.column_dimensions["D"].width = valueofwidth
ws.column_dimensions["E"].width = valueofwidth
ws.column_dimensions["F"].width = valueofwidth
ws.column_dimensions["G"].width = valueofwidth
ws.column_dimensions["H"].width = valueofwidth
ws.column_dimensions["I"].width = valueofwidth
ws.column_dimensions["J"].width = valueofwidth
ws.column_dimensions["K"].width = valueofwidth
ws.column_dimensions["L"].width = valueofwidth
ws.column_dimensions["M"].width = valueofwidth
ws.column_dimensions["N"].width = valueofwidth
# 重置所有計(jì)數(shù)器并匯總收集的統(tǒng)計(jì)信息
os.popen("adb shell dumpsys gfxinfo PackageName reset")
print "清理幀信息回到初始狀態(tài)"
# 模擬滑動(dòng)頁(yè)面操作
for i in range (1,3):
print "執(zhí)行滑動(dòng)頁(yè)面操作" + str(i) + "次"
os.system("adb shell input swipe 700 2000 700 200")
time.sleep(1)
# 過(guò)濾、篩選精確的幀時(shí)間信息
command = "adb shell dumpsys gfxinfo PackageName framestats | grep -A 120 'Flags'"
r = os.popen(command)
info = r.readlines()
# 數(shù)據(jù)處理中
print "緩存數(shù)據(jù)中......"
for line in info: #按行遍歷
# line = line.strip('\r\n')
eachline = line.split(',')
# 將行寫入Excel表格
ws.append(eachline)
# print line
# 新建sheet用來(lái)統(tǒng)計(jì)數(shù)據(jù)
resultsheet = wb.create_sheet("result",0)
resultsheet.column_dimensions["A"].width = valueofwidth
resultsheet.column_dimensions["B"].width = valueofwidth
resultsheet.column_dimensions["C"].width = valueofwidth
resultsheet.column_dimensions["D"].width = valueofwidth
resultsheet.column_dimensions["E"].width = valueofwidth
resultsheet.column_dimensions["F"].width = valueofwidth
resultsheet.column_dimensions["G"].width = valueofwidth
resultsheet.column_dimensions["H"].width = valueofwidth
resultsheet.column_dimensions["I"].width = valueofwidth
# 為結(jié)果頁(yè)添加title說(shuō)明
resultsheet.append(titlelist)
resultsheet.append(subtitlelist)
# resultsheet.RowDimension(height = 5)
# 填入公式,cell值由納秒轉(zhuǎn)換為毫秒
for i in range(3,123):
resultsheet.cell(row = i, column = 1, value = "=data!C" + str(i-1) + "-data!B"+ str(i-1))
for i in range(3,123):
value = "=(data!G" + str(i-1) + "-data!F"+ str(i-1)
resultsheet.cell(row = i, column = 2, value = value + ")/1000000")
for i in range(3,123):
value = "=(data!H" + str(i-1) + "-data!G"+ str(i-1)
resultsheet.cell(row = i, column = 3, value = value + ")/1000000")
for i in range(3,123):
value = "=(data!I" + str(i-1) + "-data!G"+ str(i-1)
resultsheet.cell(row = i, column = 4, value = value + ")/1000000")
for i in range(3,123):
value = "=(data!K" + str(i-1) + "-data!I"+ str(i-1)
resultsheet.cell(row = i, column = 5, value = value + ")/1000000")
for i in range(3,123):
value = "=(data!L" + str(i-1) + "-data!K"+ str(i-1)
resultsheet.cell(row = i, column = 6, value = value + ")/1000000")
for i in range(3,123):
value = "=(data!L" + str(i-1) + "-data!K"+ str(i-1)
resultsheet.cell(row = i, column = 7, value = value + ")/1000000")
for i in range(3,123):
value = "=(data!N" + str(i-1) + "-data!B"+ str(i-1)
resultsheet.cell(row = i, column = 8, value = value + ")/1000000")
# 插入平均值16ms的列
for i in range(3,123):
resultsheet.cell(row = i, column = 9, value = 16)
# 插入平均Frame值
resultsheet['J1'] = "平均值ms"
resultsheet['J2'] = "=AVERAGEA(H3:H122)"
# 畫(huà)圖準(zhǔn)備
chart = LineChart()
chart.title = titlename + str(j)
# chart.style = 5 #style都很丑,還不如默認(rèn)的
chart.y_axis.title = 'ms'
chart.x_axis.title = 'Frame'
chart.width = 30
chart.height = 15
# data選取范圍
data = Reference(resultsheet, min_col=8, min_row=2, max_col=9, max_row=122)
chart.add_data(data, titles_from_data=True)
# 創(chuàng)建圖表,在B3位置插入
resultsheet.add_chart(chart,"B3")
#記錄時(shí)間戳作為文件名
# filename = time.strftime('%Y%m%d_%H%M%S',time.localtime(time.time())) + ".xlsx"
# wb.save(filename)
#以執(zhí)行名稱 titlename作為文件名
filename2 = titlename + str(j) + ".xlsx"
wb.save(filename2)
# 數(shù)據(jù)完畢
print "緩存處理完畢,保存數(shù)據(jù)到本地" + str(filename2)
time.sleep(3)
Trace View的分析

重要的參數(shù):
? Cpu Time/call
? Calls + Recur
TraceView各項(xiàng)信息及意義:
Name:方法的詳細(xì)信息,包括包名和參數(shù)信息
Incl Cpu Time Cpu:執(zhí)行該方法該方法及其子方法所花費(fèi)的時(shí)間
Incl Cpu Time %:Cpu執(zhí)行該方法該方法及其子方法所花費(fèi)占Cpu總執(zhí)行時(shí)間的百分比
Excl Cpu Time Cpu:執(zhí)行該方法所話費(fèi)的時(shí)間
Excl Cpu Time %:Cpu執(zhí)行該方法所話費(fèi)的時(shí)間占Cpu總時(shí)間的百分比
Incl Real Time:該方法及其子方法執(zhí)行所話費(fèi)的實(shí)際時(shí)間,從執(zhí)行該方法到結(jié)束一共花了多少時(shí)間
Incl Real Time %:上述時(shí)間占總的運(yùn)行時(shí)間的百分比
Excl Real Time %:該方法自身的實(shí)際允許時(shí)間
Excl Real Time:上述時(shí)間占總的允許時(shí)間的百分比
Calls+Recur:調(diào)用次數(shù)+遞歸次數(shù),只在方法中顯示,在子展開(kāi)后的父類和子類方法這一欄被下面的數(shù)據(jù)代替
Calls/Total:調(diào)用次數(shù)和總次數(shù)的占比
Cpu Time/Call Cpu:執(zhí)行時(shí)間和調(diào)用次數(shù)的百分比,代表該函數(shù)消耗cpu的平均時(shí)間
Real Time/Call :實(shí)際時(shí)間于調(diào)用次數(shù)的百分比,該表該函數(shù)平均執(zhí)行時(shí)間
其他方法:
? Animator duration scale
通過(guò)在 Android 設(shè)備的設(shè)置 APP 的開(kāi)發(fā)者選項(xiàng)里打開(kāi) “ 窗口動(dòng)畫(huà)縮放 ” / “ 過(guò)渡動(dòng)畫(huà)縮放 ” / “ 動(dòng)畫(huà)程序時(shí)長(zhǎng)縮放 ”,來(lái)加速或減慢動(dòng)畫(huà)的時(shí)間,以查看加速或減慢狀態(tài)下的動(dòng)畫(huà)是否會(huì)有問(wèn)題。
? StrictMode
通過(guò)在 Android 設(shè)備的設(shè)置 APP 的開(kāi)發(fā)者選項(xiàng)里啟動(dòng) “ 嚴(yán)格模式 ” ,來(lái)查看應(yīng)用哪些操作在主線程上執(zhí)行時(shí)間過(guò)長(zhǎng)。當(dāng)一些操作違背了嚴(yán)格模式時(shí)屏幕的四周邊界會(huì)閃爍紅色,同時(shí)輸出 StrictMode 的相關(guān)信息到 LOGCAT 日志中
Reference:
一些官方參考
?Hierarchy View 官網(wǎng)介紹
https://developer.android.com/studio/profile/hierarchy-viewer-walkthru.html
?Overdraw 官網(wǎng)介紹
https://developer.android.com/studio/profile/dev-options-overdraw.html
?Profiling GPU Rendering 官網(wǎng)介紹
https://developer.android.com/studio/profile/dev-options-rendering.html
?Trace View 官網(wǎng)介紹
https://developer.android.com/studio/profile/traceview-walkthru.html
一些測(cè)試相關(guān)參考
?測(cè)試顯示性能
http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0920/3483.html
?Android 編程下的 TraceView 簡(jiǎn)介及其案例實(shí)戰(zhàn)
http://www.cnblogs.com/sunzn/p/3192231.html
?Android界面性能調(diào)優(yōu)手冊(cè)
https://testerhome.com/topics/4304
?正確使用 Android 性能分析工具——TraceView
https://testerhome.com/topics/5049
?【Bugly干貨分享】那些年我們用過(guò)的顯示性能指標(biāo)
http://blog.csdn.net/tencent_bugly/article/details/51354517