當前位置:首頁 » 安卓系統 » android幀率測試

android幀率測試

發布時間: 2022-12-13 00:31:37

① Android流暢度評估及卡頓優化

Google定義:界面呈現是指從應用生成幀並將其顯示在屏幕上的動作。要確保用戶能夠流暢地與應用互動,應用呈現每幀的時間不應超過16ms,以達到每秒60幀的呈現速度(為什麼是60fps?)。
如果應用存在界面呈現緩慢的問題,系統會不得不跳過一些幀,這會導致用戶感覺應用不流暢,我們將這種情況稱為卡頓。

來源於: Google Android的為什麼是60fps?

16ms意味著1000/60hz,相當於60fps。這是因為人眼與大腦之間的協作無法感知超過60fps的畫面更新。12fps大概類似手動快速翻動書籍的幀率, 這明顯是可以感知到不夠順滑的。24fps使得人眼感知的是連續線性的運動,這其實是歸功於運動模糊的效果。 24fps是電影膠圈通常使用的幀率,因為這個幀率已經足夠支撐大部分電影畫面需要表達的內容,同時能夠最大的減少費用支出。 但是低於30fps是 無法順暢表現絢麗的畫面內容的,此時就需要用到60fps來達到想要的效果,超過60fps就沒有必要了。如果我們的應用沒有在16ms內完成屏幕刷新的全部邏輯操作,就會發生卡頓。

首先要了解Android顯示1幀圖像,所經歷的完整過程。

如圖所示,屏幕顯示1幀圖像需要經歷5個步驟:

常見的丟幀情況: 渲染期間可能出現的情況,渲染大於16ms和小於16ms的情況:

上圖中應該繪制 4 幀數據 , 但是實際上只繪制了 3 幀 , 實際幀率少了一幀

判斷APP是否出現卡頓,我們從通用應用和游戲兩個緯度的代表公司標准來看,即Google的Android vitals性能指標和地球第一游戲大廠騰訊的PrefDog性能指標。

以Google Vitals的卡頓描述為准,即呈現速度緩慢和幀凍結兩個維度判斷:

PerfDog Jank計算方法:

幀率FPS高並不能反映流暢或不卡頓。比如:FPS為50幀,前200ms渲染一幀,後800ms渲染49幀,雖然幀率50,但依然覺得非常卡頓。同時幀率FPS低,並不代表卡頓,比如無卡頓時均勻FPS為15幀。所以平均幀率FPS與卡頓無任何直接關系)

當了解卡頓的標准以及渲染原理之後,可以得出結論,只有丟幀情況才能准確判斷是否卡頓。

mpsys 是一種在設備上運行並轉儲需要關注的系統服務狀態信息的 Android 工具。通過向 mpsys 傳遞 gfxinfo 命令,可以提供 logcat 格式的輸出,其中包含與錄制階段發生的動畫幀相關的性能信息。

藉助 Android 6.0(API 級別 23),該命令可將在整個進程生命周期中收集的幀數據的聚合分析輸出到 logcat。例如:

這些總體統計信息可以得到期間的FPS、Jank比例、各類渲染異常數量統計。

命令 adb shell mpsys gfxinfo <PACKAGE_NAME> framestats 可提供最近120個幀中,渲染各階段帶有納秒時間戳的幀時間信息。

關鍵參數說明:

通過gfxinfo輸出的幀信息,通過定時reset和列印幀信息,可以得到FPS(幀數/列印間隔時間)、丟幀比例((janky_frames / total_frames_rendered)*100 %)、是否有幀凍結(幀耗時>700ms)。
根據第2部分的通用應用卡頓標准,可以通過丟幀比例和幀凍結數量,准確判斷當前場景是否卡頓。並且通過定時截圖,還可以根據截圖定位卡頓的具體場景。

如上圖所示,利用gfxinfo開發的檢查卡頓的小工具,圖中參數和卡頓說明如下:

根據上面對gfxinfo的幀信息解析,可以准確計算出每一幀的耗時。從而可以開發出滿足騰訊PerfDog中關於普通卡頓和嚴重卡頓的判斷。

依賴定時截圖,即可准確定位卡頓場景。如下圖所示(此處以PerfDog截圖示例):

通過第3部分的卡頓評估方法,我們可以定位到卡頓場景,但是如何定位到具體卡頓原因呢。

首先了解卡頓問題定位工具,然後再了解常見的卡頓原因,即可通過復現卡頓場景的同時,用工具去定位具體卡頓問題。

重點就是,充分利用gfxinfo輸出的幀信息,對卡頓問題進行分類。

了解了高效定位卡頓的方法和卡頓問題定位工具,再熟悉一下常見的卡頓原因,可以更熟練的定位和優化卡頓。

SurfaceFlinger 負責 Surface 的合成,一旦 SurfaceFlinger 主線程調用超時,就會產生掉幀。
SurfaceFlinger 主線程耗時會也會導致 hwc service 和 crtc 不能及時完成,也會阻塞應用的 binder 調用,如 dequeueBuffer、queueBuffer 等。

後台進程活動太多,會導致系統非常繁忙,cpu io memory 等資源都會被佔用,這時候很容易出現卡頓問題,這也是系統這邊經常會碰到的問題。
mpsys cpuinfo 可以查看一段時間內 cpu 的使用情況:

當線程為 Runnable 狀態的時候,調度器如果遲遲不能對齊進行調度,那麼就會產生長時間的 Runnable 線程狀態,導致錯過 Vsync 而產生流暢性問題。

system_server 的 AMS 鎖和 WMS 鎖 , 在系統異常的情況下 , 會變得非常嚴重 , 如下圖所示 , 許多系統的關鍵任務都被阻塞 , 等待鎖的釋放 , 這時候如果有 App 發來的 Binder 請求帶鎖 , 那麼也會進入等待狀態 , 這時候 App 就會產生性能問題 ; 如果此時做 Window 動畫 , 那麼 system_server 的這些鎖也會導致窗口動畫卡頓。

Android P 修改了 Layer 的計算方法 , 把這部分放到了 SurfaceFlinger 主線程去執行, 如果後台 Layer 過多,就會導致 SurfaceFlinger 在執行 rebuildLayerStacks 的時候耗時 , 導致 SurfaceFlinger 主線程執行時間過長。

主線程執行 Input Animation Measure Layout Draw decodeBitmap 等操作超時都會導致卡頓 。

Activity resume 的時候, 與 AMS 通信要持有 AMS 鎖, 這時候如果碰到後台比較繁忙的時候, 等鎖操作就會比較耗時, 導致部分場景因為這個卡頓, 比如多任務手勢操作。

應用裡面涉及到 WebView 的時候, 如果頁面比較復雜, WebView 的性能就會比較差, 從而造成卡頓。

如果屏幕幀率和系統的 fps 不相符 , 那麼有可能會導致畫面不是那麼順暢. 比如使用 90 Hz 的屏幕搭配 60 fps 的動畫。

由上面的分析可知對象分配、垃圾回收(GC)、線程調度以及Binder調用 是Android系統中常見的卡頓原因,因此卡頓優化主要以下幾種方法,更多的要結合具體的應用來進行:

在計算機和通信領域,幀是一個包括「幀同步串列」的數字數據傳輸單元或數字數據包。
在視頻領域,電影、電視、數字視頻等可視為隨時間連續變換的許多張畫面,其中幀是指每一張畫面。

② 如何測量Android應用的幀率FPS

方法如下:

1.打開網路瀏覽器,在輸入欄里輸入gltools,並點擊下載安裝。

③ Android性能測試(內存、cpu、fps、流量、GPU、電量)——adb篇

3)查看進程列表:adb shell "ps",同時也能獲取到應用的UID,方式如下(不需root許可權):

u0_a開頭的都是Android的應用進程,Android的應用的UID是從10000開始,到19999結束,可以在Process.java中查看到(FIRST_APPLICATION_UID和LAST_APPLICATION_UID),u0_a後面的數字就是該應用的UID值減去FIRST_APPLICATION_UID所得的值,所以,對於截圖這個應用進程,它是u0_a155,按前面的規制,它的UID就是155 + FIRST_APPLICATION_UID = 10155。

VSS - Virtual Set Size 虛擬耗用內存(包含共享庫佔用的內存)
RSS - Resident Set Size 實際使用物理內存(包含共享庫佔用的內存)
PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫佔用的內存)
USS - Unique Set Size 進程獨自佔用的物理內存(不包含共享庫佔用的內存)
一般來說內存佔用大小有如下規律:VSS >= RSS >= PSS >= USS

使用 adb shell "mpsys meminfo -s <pakagename | pid>"命令,輸出結果分以下4部分:

PS:在apk內調用運行獲取其他app的內存數據則需要root許可權

adb命令:adb shell mpsys gfxinfo <package | pid>

正常情況下幀率應該在16.67ms左右,1秒60幀,執行結果如下:

詳細計算方法如下:

還有一個命令是: adb shell mpsys SurfaceFlinger --latency LayerName

其中LayerName在各個不同系統中獲取的命令是不一樣的
在Android 6系統直接就是SurfaceView
在Android 7系統中可以通過 mpsys window windows | grep mSurface | grep SurfaceView 然後通過數據截取到
在Android 8系統中可以通過 mpsys SurfaceFlinger | grep android包名獲取到

執行命令結果如下:

計算方法比較簡單,一般列印出來的數據是129行(部分機型列印兩次257行,但是第一部分是無效數據,取後半部分),取len-2的第一列數據為end_time,取len-128的第一列數據為start_time
fps = 127/((end_time - start_time) / 1000000.0)
至於為啥要取第一列數據,這里不做過多介紹,歡迎參看這兩篇文章
老羅的文章SurfaceView原理
Android性能測試之fps獲取
至於為啥要處於1000000,因為命令列印出來的是納秒單位,要轉為毫秒進行計算,127就是因為命令一次列印出來127幀的數據而已

有兩種方法可以獲取
1) adb shell "top -n 5 | grep <package | pid>" ,第三列就是實時監控的CPU佔用率(-n 指定執行次數,不需root許可權),這邊top命令執行需要2到3s左右,一般可以採用busybox 的top命令執行,效率會快很多

2) adb shell "mpsys cpuinfo | grep <package | pid>"
兩種方法直接區別在於,top是持續監控狀態,而mpsys cpuinfo獲取的實時CPU佔用率數據

adb命令:adb shell "mpsys batterystats < package | pid>" (Android 5.0後引入)
獲取單個應用的耗電量信息,具體返回結果待研究

adb命令:adb shell "mpsys battery"
出現信息解讀:
AC powered:false 是否連接AC(電源)充電線
USB powered:true 是否連接USB(PC或筆記本USB插口)充電
Wireless powered:false 是否使用了無線電源
status: 1 電池狀態,2為充電狀態,其他為非充電狀態
level:58 電量(%)
scale: 100. 電量最大數值
voltage: 3977 當前電壓(mV)
current now: -335232. 當前電流(mA)
temperature:355 電池溫度,單位為0.1攝氏度

adb 命令:adb shell "mpsys< package | pid> | grep UID" [通過ps命令,獲取app的UID(安裝後唯一且固定)]
adb shell cat /proc/uid_stat/UID/tcp_rcv [cat為查看命令,讀取tcp_rcv獲取應用接收流量信息(設備重啟後清零)]
adb shell cat /proc/uid_stat/UID/tcp_snd [cat為查看命令,讀取tcp_snd獲取應用發送流量信息(設備重啟後清零)]
計算流量消耗步驟:

或者還有一種方式獲取應用流量消耗:

首先判斷類型:
cat /sys/class/thermal/thermal_zone*/type

只有紅框框出來的是有效的
cat /sys/class/thermal/thermal_zone*/temp
獲取CPU溫度

mpsys battery | grep temperature 單位0.1攝氏度

獲取/proc/stat文件內容(無許可權限制)

總的cpu時間片是 total = user+nice+system+idle+iowait+irq+softirq
忙碌時間為 notidle = user+nice+system +iowait+irq+softirq
cpu使用率計算方法為,先取開始的total值和忙碌時間notidle,隔一段時間片,再取一次計算total2,notidle2, cpuuse = (notidle2 – notidle) * 100 / (total2 - total)%

PS:由於Android 8許可權收緊,在Android 8系統手機內apk內讀取文件內容為空,需要shell許可權才可獲取文件內容,下同

讀/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq文件的值,X不定,看是幾核手機,scaling_cur_freq是否存在也不一定,需要判斷

至於為啥不取cpuinfo_cur_freq文件的值,原因是android 6,7系統獲取的時候,這個文件shell沒有讀取許可權,需要root許可權

參考文章: https://blog.csdn.net/long_meng/article/details/45934899

Android 6,7系統可執行
mpsys window windows | grep "mCurrentFocus"

執行結果一般為類似:
mCurrentFocus=Window{81caaa5 u0 com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity}
按照一定規則把com.tencent.mobileqq提取出來即可

直接apk內讀取文件即可,不需要shell許可權(支持到Android8)
Gpu使用率獲取:會得到兩個值,(前一個/後一個)*100%=使用率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpubusy

Gpu工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/gpuclk
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq

Gpu最大、最小工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/min_freq

Gpu可用頻率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies

Gpu可用工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_governors

Gpu當前工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/governor

④ APP性能測試(1):FPS測試

adb 計算幀率: https://zhuanlan.hu.com/p/67056913
adb 計算幀率: https://www.huaweicloud.com/articles/12566219.html

幀率:FPS是圖像領域中的定義,是指畫面每秒傳輸幀數,通俗來講就是指動畫或視頻的畫面數。30FPS是一般錄像的常用幀數,30FPS在快速動作的時候會感覺不流暢。60FPS是一般游戲的常用幀數。

絕大部分時間兩者(Android和IOS)都能保持60FPS左右的滿幀率。但都會有偶爾的掉幀。並且Android上要比IOS上嚴重很多。掉幀導致卡頓,用戶必然會感覺到掉幀那一刻的不流暢。

FPS是圖像領域中的定義,是指畫面每秒傳輸幀數,通俗來講就是指動畫或視頻的畫面數。FPS是測量用於保存、顯示動態視頻的信息數量。每秒鍾幀數愈多,所顯示的動作就會愈流暢一般來說,Android設備的屏幕刷新率為 60幀/s ,要保持畫面流暢不卡頓,要求每一幀的時間不超過 1000/60=16.6ms ,這就是16ms的黃金准則,如果中間的某些幀的渲染時間超過16ms,就會導致這段時間的畫面發生了跳幀,因此原本流暢的畫面變發生了卡頓。

FPS 通常作為衡量應用是否流暢的標准。

FPS 即 Frames per Second(每秒顯示的幀數),用於測量顯示幀數的度量。幀數為 0 說明頁面處於靜止,只要頁面動起來,這個幀數就會有變化,然後再趨於靜止,頁面滾動起來幀數整體呈現 「非對稱」 拋物線走勢。接下來看一張圖直觀感受一下:

通過上圖我們能看出 FPS 值的大小對畫面流暢度的影響,每一幀都是靜止的圖像,快速連續地顯示幀便形成了運動的假象,因此高幀率可以得到更流暢、更逼真的動畫。

幀延遲的高低可以通過幀時間(Frame Time)來判定。我們參考顯示器的 60Hz 刷新率進行計算,它意味著每秒刷新 60 幀,每幀大約用時 16.7 毫秒。畫面中每幀生成時間如果與 16.7 毫秒很接近,那麼全程畫面的幀數就很穩定,更接近理想的 60 幀每秒。

如果每幀生成時間高於 16.7 毫秒,也就意味著渲染這一場景所花費的時間比其他幀更多,造成畫面跟不上,進而帶來顯示卡頓。
手機的 CPU 處理速率、屏幕尺寸、內存及顯存的大小都影響著 APP 幀率的大小,這些因素在一定程度上約束著准備數據和數據傳到屏幕的時間。再者,GUI 軟體架構在一定程度上也影響著應用幀率的大小。

在同等機器環境下,除去 CPU、屏幕尺寸及系統 GUI 等固有數據傳輸耗時,要提升應用 FPS 就要減少視圖渲染的時間。

1、盡量不要在刷新時做耗時操作,例如准備數據,創建圖片,圖片變換等,數據和圖片都應該在之前就載入到內存中,圖片變換用 canvas 的變換來實現。

2、同一個界面中多個動畫重疊出現時,盡量將動畫的刷新過程統一刷新,避免頻繁的 invalidate,尤其是多個動畫有時序上的關系時更應該統一。

3、盡量使用帶有參數的 invalidate 來刷新,這樣可以減少很多運算量。

APP也需要關注FPS、Jank及卡頓率。只是需要區分使用場景,如:

只需關注FPS,理論FPS應該為0,否則,說明有冗餘刷新,容易引起手機發熱及耗電。

只需關注FPS,FPS處於合適值即可,無需高頻刷新。

需要關注FPS、Jank及卡頓率。手機交互靈敏度就是來源於此,Android系統才出黃油計劃Jank。一般滑動狀態下,幀率越高越好,Jank越小越好。

需要關注FPS、Jank及卡頓率,視頻卡頓直接影響用戶。視頻一般幀率18-24幀,Jank=0。比如微信播放視頻、視頻播放器等。

註:
引用來源

⑤ 如何測量Android應用的幀率FPS

測量Android應用的幀率FPS的方法如下:

  1. 首先打開設置,進行如下操作(「設置」->"開發者選項",然後勾選「GPU顯示配置文件」),以打開GPU呈現模式分析。如圖:


⑥ 如何測量android應用的幀率fps和統計

Android應用的幀率FPS是衡量應用流暢度的一個非常重要的指標,可以根據FPS對應用做一些優化,那麼在開發過程中如何來測量我們的應用的FPS呢?

工具/原料

  • Eclipse

  • 三星GT-P3110

  • 方法/步驟

  • 在設置里打開GPU呈現模式分析。點擊Android設備的「設置」->"開發者選項",然後勾選「GPU顯示配置文件」。

  • 從圖中可以看出來,我這個應用的流暢度是很低的,正常情況下幀率應該在16ms左右,如果1秒60幀的話,而且Execute時間太長!所以是需要進行優化的。

  • 是不是很簡單,如果覺得有用,請為小編投上支持的一票,小編會繼續努力謝謝你的支持哦。

⑦ 如何測量Android應用的幀率FPS

  • 通過 [設置]->[開發者選項]->[GPU呈現模式分析] ->[在屏幕上顯示為條形圖] 進行直觀的取樣,截圖如下:

    繪制過程中的不同顏色具有不同的含義,詳細解釋請移步>> 官網查看更多。

    那麼是不是說我只需要打開界面去數一下超過綠色閾值的柱狀圖有多少就可以觀察我們應用的流暢度了?然而並沒有,因為這個方式獲取到的渲染時間只是UI主線程上的繪制行為,目前我所接手的項目,採用的方式是捕捉相機的數據然後放到GPU中去進行繪制,有單獨的繪制線程,單獨的視圖,所以這個方案並不適合我手上的項目。

熱點內容
android版本控制 發布:2025-03-19 06:20:59 瀏覽:180
安卓手機怎麼反色 發布:2025-03-19 06:15:19 瀏覽:822
安卓開視頻時聲音小怎麼辦 發布:2025-03-19 06:08:18 瀏覽:579
文件伺服器訪問速度慢 發布:2025-03-19 05:45:36 瀏覽:637
python的下載與安裝 發布:2025-03-19 05:41:38 瀏覽:771
安卓怎麼用手電筒檢測換屏 發布:2025-03-19 05:30:33 瀏覽:674
蘋果6怎麼設置短密碼 發布:2025-03-19 04:44:41 瀏覽:20
三人樂隊怎麼配置 發布:2025-03-19 04:34:42 瀏覽:917
趣編程入口 發布:2025-03-19 04:25:09 瀏覽:942
a的存儲形式 發布:2025-03-19 04:24:00 瀏覽:792