Android 的用戶界面渲染是從應(yīng)用中 "生成" 一幀然后顯示在屏幕上,為了確保用戶能夠獲得順暢的交互體驗(yàn),您的應(yīng)用需要根據(jù)設(shè)備的刷新率完成每一幀的 "生成"。例如,Pixel 6 設(shè)備支持每秒最多渲染 90 幀,這就意味著應(yīng)用的每一幀任務(wù)都要在 1000/90 = 11ms 內(nèi)完成,如果沒(méi)有,Android 框架就會(huì)將這一幀的渲染跳過(guò),用戶就會(huì)從視覺(jué)上感受到界面運(yùn)行緩慢,我們稱(chēng)這種情況為 "卡頓"。
出現(xiàn)卡頓的原因有很多種,例如,由應(yīng)用導(dǎo)致的卡頓或由 SurfaceFlinger 導(dǎo)致的卡頓。本文重點(diǎn)關(guān)注由應(yīng)用導(dǎo)致的卡頓,以及 Android Studio 提供的用于發(fā)現(xiàn)和消除這些卡頓的工具,方法是在應(yīng)用交互的過(guò)程中檢查記錄的軌跡來(lái)解決應(yīng)用的性能問(wèn)題。
注意:本文所展示的是Android Studio Chipmunk 更新后的卡頓檢測(cè)界面,使用 Android 12 (API 級(jí)別 31) 或更高版本的真機(jī)或模擬器。
從實(shí)時(shí)交互記錄軌跡
以下示例使用 GitHub 性能示例倉(cāng)庫(kù)中的 JankStatsSample 應(yīng)用來(lái)展示如何使用 CPU 性能分析器鎖定卡頓的原因:
https://github.com/android/performance-samples/tree/main/JankStatsSample 1. 打開(kāi) JankStatsSample 并運(yùn)行應(yīng)用。 2. 打開(kāi) Android Studio 底部的 Profiler 標(biāo)簽頁(yè)。
3. 點(diǎn)擊 Profiler 左側(cè)窗格中的 + 圖標(biāo)啟動(dòng)新的性能分析會(huì)話,然后選擇要運(yùn)行性能分析器的設(shè)備名稱(chēng)和應(yīng)用進(jìn)程。
注意: 雖然可以分析 "可調(diào)試應(yīng)用" (debuggable app),但推薦做法是分析 "可分析應(yīng)用" (profileable app),因?yàn)榉治?"可調(diào)試應(yīng)用" 會(huì)導(dǎo)致性能開(kāi)銷(xiāo)顯著增加。更多詳細(xì)信息,請(qǐng)參閱關(guān)于可分析應(yīng)用的文檔:
https://developer.android.google.cn/studio/profile#profileable-apps
4. 點(diǎn)擊 CPU 行。
5. 選擇 System Trace Recording,點(diǎn)擊 Record。
6. 與應(yīng)用互動(dòng)以收集數(shù)據(jù),然后點(diǎn)擊 Stop 按鈕。Android Studio 將顯示 Display 窗格,其中可見(jiàn)卡頓幀,也可以選中 All Frames 復(fù)選框,讓軌跡記錄也顯示非卡頓幀。
將鼠標(biāo)指針懸停在幀上或點(diǎn)擊幀,即可查看詳細(xì)的幀信息。如果選中 All Frames 復(fù)選框,將有三種類(lèi)型的幀。
綠色幀 不卡頓的正常幀
紅色幀 由于應(yīng)用進(jìn)程運(yùn)行時(shí)間超出預(yù)期并且錯(cuò)過(guò)了預(yù)期幀時(shí)長(zhǎng)的截止時(shí)間,被視為卡頓的幀。從應(yīng)用開(kāi)發(fā)者的角度來(lái)看,可操作幀通常是紅色幀。
黃色幀 被視為緩沖區(qū)填充的幀,這表示應(yīng)用會(huì)在呈現(xiàn)前一幀之前不斷將幀發(fā)送到系統(tǒng)。這通常是前一幀卡頓所致,應(yīng)用開(kāi)發(fā)者面對(duì)黃幀無(wú)能為力。
選中 Lifecycle 復(fù)選框,可以切換顯示/隱藏四個(gè)附加軌跡。
四個(gè)軌跡:
Application
Composition
Frames on display
Android Studio Bumblebee (2021.1.1) 穩(wěn)定版中已經(jīng)加入了這些軌跡信息的顯示。您可以在文檔中查看每個(gè)軌跡的詳細(xì)說(shuō)明:
https://developer.android.google.cn/studio/profile/jank-detection#jank-detection-android-11
檢查卡頓幀
接下來(lái),我們來(lái)找出卡頓幀出現(xiàn)的原因。
1.在 Janky frames 軌跡中選擇一個(gè)卡頓幀,Display 窗格將突出顯示相應(yīng)的生命周期數(shù)據(jù),Threads 窗格將突出顯示相應(yīng)的線程數(shù)據(jù)。
虛線 Deadline 代表截止時(shí)間。當(dāng)幀的時(shí)長(zhǎng)超過(guò)該截止時(shí)間時(shí),該幀即被視為卡頓。
您還可以在 Android Studio 的右側(cè)窗格中查看詳細(xì)分析。
2. 如果您看一下應(yīng)用主線程相應(yīng)的軌跡窗格,可以看到大量的時(shí)間花費(fèi)在 "View#draw" 中。
此外,如詳細(xì)分析窗格中的主線程狀態(tài)所示,大量線程所處的狀態(tài)是正在休眠。
3. 我們看一下調(diào)用 View#draw 的代碼。View#onDraw 在 JankyView 類(lèi)中被復(fù)寫(xiě):
https://github.com/android/performance-samples/blob/main/JankStatsSample/app/src/main/java/com/example/jankstats/JankyView.kt#L36
override fun onDraw(canvas: Canvas) { simulateJank() super.onDraw(canvas)}從 onDraw 調(diào)用的 simulateJank 方法定義如下: https://github.com/android/performance-samples/blob/main/JankStatsSample/app/src/main/java/com/example/jankstats/tools/simulateJank.kt#L29
fun simulateJank( jankProbability: Double = 0.3, extremeJankProbability: Double = 0.02) { val probability = nextFloat() if (probability > 1 - jankProbability) { val delay = if (probability > 1 - extremeJankProbability) { nextLong(500, 700) } else { nextLong(32, 82) } try { // 在分析器中通過(guò)軌跡使卡頓更易被鎖定 trace("Jank Simulation") { Thread.sleep(delay) } } catch (e: Exception) { } }}然后,您可以發(fā)現(xiàn)在 simulateJank 方法中調(diào)用了 Thread.sleep。顯然,這是因?yàn)?JankStatsSample 應(yīng)用是為了模擬卡頓而特別創(chuàng)建的。但值得注意的是,從卡頓幀的概覽再到更詳細(xì)的分析,可以找出實(shí)際代碼。 注意:雖然在這個(gè)示例中調(diào)用 Thread.sleep 明顯有問(wèn)題,但實(shí)際上,在優(yōu)化實(shí)際應(yīng)用代碼時(shí),您將面臨更困難的決定。Microbenchmark 開(kāi)發(fā)庫(kù)有助于衡量所做的更改能否達(dá)成預(yù)期效果: https://developer.android.google.cn/topic/performance/benchmarking/microbenchmark-overview 注意: 系統(tǒng)軌跡顯示的是由平臺(tái)代碼和屬于應(yīng)用的庫(kù)捕獲的多個(gè)部分,通常沒(méi)有足夠的信息。添加自定義軌跡能夠改善這樣的情況,添加的方法之一是使用 AndroidX Tracing 庫(kù)中的 trace(“MySection”) { /* this will be in the trace */ }。
AndroidX Tracing
https://developer.android.google.cn/reference/androidx/tracing/Trace
例如,此示例中的 trace(“Jank Simulation”) { … } 顯示在相應(yīng)線程的軌跡部分中。
如需了解關(guān)于讀取軌跡和添加自定義軌跡的更多信息,請(qǐng)參閱系統(tǒng)軌跡概述:
https://developer.android.google.cn/topic/performance/tracing
4. 將代碼更改為在 onDraw 中不去調(diào)用 simulateJank 方法,然后查看是否仍然存在卡頓幀。
override fun onDraw(canvas: Canvas) { // simulateJank() super.onDraw(canvas)}
這一次,重新運(yùn)行系統(tǒng)軌跡錄制時(shí),您會(huì)發(fā)現(xiàn)與應(yīng)用的交互不再有卡頓幀啦。
加載保存的軌跡
您也可以遵循以下步驟,保存軌跡并后續(xù)再加載。保存并加載軌跡后,您可以比較不同版本的跟蹤記錄或者與他人共享。 注意:您還可以使用 Macrobenchmark 庫(kù)獲取系統(tǒng)軌跡: https://developer.android.google.cn/topic/performance/benchmarking/macrobenchmark-overview 1. 按照從第 1 步至第 6 步的相同步驟,通過(guò)實(shí)時(shí)交互操作錄制軌跡。 2. 點(diǎn)擊保存圖標(biāo)導(dǎo)出記錄。
3. 然后,導(dǎo)航到 + -> Load from file… 加載已保存的系統(tǒng)軌跡錄制,選擇上一步中導(dǎo)出的已保存文件。
?
4. 選擇要分析的進(jìn)程。顯示進(jìn)程列表下拉菜單后,輸入進(jìn)程名稱(chēng)的一部分即可快速查找。
然后,您可以加載保存的軌跡,像從實(shí)時(shí)互動(dòng)錄制一樣查看卡頓幀。
總結(jié)
本期內(nèi)容就到這里了,從 Android Studio Chipmunk 開(kāi)始,您能夠看到更精準(zhǔn)的性能分析數(shù)據(jù),更快鎖定應(yīng)用卡頓。
請(qǐng)查看文檔進(jìn)一步了解 CPU 性能分析器的用法,也歡迎您前往 Android Studio 中的 "Help -> Submit Feedback" 幫助我們改進(jìn)工具。
原文標(biāo)題:在 Android Studio 中使用 CPU 性能分析器鎖定界面卡頓
文章出處:【微信公眾號(hào):谷歌開(kāi)發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
Android
+關(guān)注
關(guān)注
12文章
3973瀏覽量
130283 -
屏幕
+關(guān)注
關(guān)注
7文章
1218瀏覽量
56561 -
模擬器
+關(guān)注
關(guān)注
2文章
894瀏覽量
44423
原文標(biāo)題:在 Android Studio 中使用 CPU 性能分析器鎖定界面卡頓
文章出處:【微信號(hào):Google_Developers,微信公眾號(hào):谷歌開(kāi)發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄

#Android開(kāi)發(fā) Android Studio使用及配置_2.4 Android Studio的界面和功能
Android Studio由于下載的SDK Tools版本造成無(wú)法更新SDK問(wèn)題
Linux下配置Android Studio與Eclipse
迅為4412開(kāi)發(fā)板安裝Android Studio(一)
MIUI迎來(lái)更新:支持Android 5.0/5.1/6.0/7.0機(jī)型 大幅減少卡頓
微軟Visual Studio Online更新后支持Docker鏡像和Dockerfile
如何將機(jī)智云源碼導(dǎo)入Android Studio

Android Studio Bumblebee 穩(wěn)定版亮點(diǎn)與新功能
Android Studio Dolphin中重要的功能更新和改進(jìn)
詳解Android Studio Chipmunk新增功能
Android Studio Dolphin穩(wěn)定版正式發(fā)布
Android Studio引入AI編程助手Studio Bot

評(píng)論