一、卡頓原因
屏幕1秒60幀麻敌,平均每幀16.6毫秒栅炒,如果代碼實(shí)現(xiàn)不佳,或者過于復(fù)雜术羔,導(dǎo)致一幀繪制時(shí)間大于16.6毫秒赢赊,則無法完成繪制,造成丟幀级历,連續(xù)出現(xiàn)掉幀释移,在現(xiàn)象上表現(xiàn)為卡頓。
二寥殖、App啟動時(shí)間
1玩讳、方法1
adb shell am start -W com.zhoupushuju.zhouyi/com.rnmobx.MainActivity
結(jié)果
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.zhoupushuju.zhouyi/com.rnmobx.MainActivity }
Status: ok
LaunchState: COLD
Activity: com.zhoupushuju.zhouyi/com.rnmobx.MainActivity
TotalTime: 931
WaitTime: 934
Complete
- LaunchState:啟動方式,此為冷啟動
- Activity:啟動頁面
- TotalTime:啟動Activity的總耗時(shí)
- WaitTime:啟動Activity的總耗時(shí)+少量的系統(tǒng)耗時(shí)
2嚼贡、方法2
adb logcat -b all | grep am_activity_launch_time
結(jié)果
[0,78748358,com.zhoupushuju.zhouyi/com.rnmobx.MainActivity,931]
三熏纯、AndroidStudio Profile使用
1、在 Android 12 及更高版本上檢測卡頓情況
對于搭載 Android 12(API 級別 31)或更高版本的設(shè)備粤策,CPU 性能分析器中 Display 窗格下的 Janky Frameworks 軌道中會顯示捕獲的軌跡樟澜。
如需檢測卡頓情況,請按以下步驟操作:
-
在 Android Studio 中叮盘,依次選擇 View > Tool Windows > Profiler秩贰,或點(diǎn)擊工具欄中的 Profile 圖標(biāo)
如果 Select Deployment Target 對話框顯示提示,請選擇要將您的應(yīng)用部署到哪個(gè)設(shè)備以進(jìn)行性能分析柔吼。如果您已通過 USB 連接設(shè)備但系統(tǒng)未列出該設(shè)備毒费,請確保您已啟用 USB 調(diào)試。
點(diǎn)擊 CPU 時(shí)間軸上的任意位置以打開 CPU 性能分析器愈魏。
從 CPU 性能分析器的配置菜單中選擇 System Trace觅玻,然后點(diǎn)擊 Record艇棕。完成與應(yīng)用的交互后,點(diǎn)擊 Stop串塑。
-
您應(yīng)該會在 Display 下方看到 Janky frames 軌道沼琉。默認(rèn)情況下,性能分析器只會將卡頓幀顯示為有待調(diào)查的候選對象桩匪。在每個(gè)卡頓幀中打瘪,紅色部分突出顯示了相應(yīng)幀超出其渲染截止時(shí)間的時(shí)長。
-
發(fā)現(xiàn)卡頓幀后傻昙,點(diǎn)擊該幀闺骚;可根據(jù)需要按 M 鍵調(diào)整縮放程度以聚焦到所選幀。相關(guān)事件會在以下線程中突出顯示:主線程妆档、RenderThread 和 GPU completion僻爽。
-
通過選中或取消選中 All Frames 和 Lifecycle 復(fù)選框,您可以根據(jù)需要查看所有幀或呈現(xiàn)時(shí)間的細(xì)分?jǐn)?shù)據(jù)贾惦。
2胸梆、在Android 11上檢測卡頓情況
對于搭載 Android 11(API 級別 30)的設(shè)備,CPU 性能分析器的 Frame Lifecycle 部分會顯示捕獲的軌跡须板。
Frame Lifecycle 部分包含層名稱和四個(gè)軌跡碰镜。每個(gè)軌跡分別代表幀呈現(xiàn)流水線中的一個(gè)階段。Frame Lifecycle 元素如下:
- Frame Lifecycle (層名稱):該部分的標(biāo)題包含用括號括起來的層名稱习瑰。層是單個(gè)組合單元绪颖。
-
Application:此軌跡顯示從緩沖區(qū)被應(yīng)用移出隊(duì)列到重新回到隊(duì)列的時(shí)間。這通常對應(yīng)于
RenderThread
中的軌跡事件甜奄。 - Wait for GPU:此軌跡顯示 GPU 擁有相應(yīng)緩沖區(qū)的時(shí)長柠横。該時(shí)長指的是,從相應(yīng)緩沖區(qū)的內(nèi)容被發(fā)送至 GPU课兄,到 GPU 利用相應(yīng)緩沖區(qū)的內(nèi)容完成其工作牍氛,期間所經(jīng)歷的時(shí)間。這并不表示 GPU 在此期間僅使用相應(yīng)緩沖區(qū)的內(nèi)容工作第喳。如需詳細(xì)了解給定時(shí)間內(nèi) GPU 執(zhí)行的工作糜俗,您可能需要使用 Android GPU 檢查器。
- Composition:此軌跡顯示曲饱,從 SurfaceFlinger 占有相應(yīng)緩沖區(qū)并發(fā)送相應(yīng)緩沖區(qū)的內(nèi)容以進(jìn)行合成,到相應(yīng)緩沖區(qū)的內(nèi)容被發(fā)送到顯示屏珠月,期間所經(jīng)歷的時(shí)間扩淀。
- Frames on display:此軌跡顯示相應(yīng)幀在屏幕上的時(shí)長。
Frame Lifecycle 部分說明了幀緩沖區(qū)在呈現(xiàn)流水線的不同階段之間的切換方式啤挎。幀按幀號進(jìn)行顏色編碼驻谆,以便更輕松地跟蹤特定幀卵凑。
Android Studio 還會在 All Frames 標(biāo)簽頁中以表格格式顯示軌跡中的所有幀。
Frame #胜臊、Application勺卢、Wait for GPU 和 Composition 列表示的數(shù)據(jù)與上方 Frame Lifecycle 部分的軌跡表示的數(shù)據(jù)一樣。Frame Duration 列表示從 Application 開始到 Frames on Display 開始所經(jīng)歷的時(shí)間象对。這本質(zhì)上是端到端呈現(xiàn)幀的時(shí)長黑忱。
您可以按任意列對“Frames”表進(jìn)行排序,以便快速找到最短或最長的幀勒魔。該表還支持分頁控件甫煞,您可以借助這些控件瀏覽數(shù)以百計(jì)的幀。
如需在 Android 11 上檢測和調(diào)查卡頓情況冠绢,請按以下步驟操作:
-
按 Application 列對 All Frames 表進(jìn)行降序排序抚吠,使耗時(shí)最長的幀首先顯示。
-
找到運(yùn)行時(shí)間最長的幀弟胀,然后選擇表中的一行楷力。這將在左側(cè)的時(shí)間軸視圖中放大所選的幀。
-
在 Frame Lifecycle 和 Threads 部分查找相關(guān)線程孵户。
3弥雹、在Android 10及更低版本上檢測卡頓情況
對于搭載 Android 10(API 級別 29)及更低版本的設(shè)備,相關(guān)的操作系統(tǒng)圖形管道信息會顯示在 CPU 性能分析器系統(tǒng)軌跡中的單個(gè)部分延届,稱為 Display剪勿。
-
Frames:此部分顯示應(yīng)用中的界面線程和
RenderThread
軌跡事件。時(shí)長超過 16 毫秒的事件會以紅色表示方庭,以突出顯示潛在的卡頓幀厕吉,因?yàn)樗鼈兂隽艘?60 幀/秒 (fps) 的速度進(jìn)行呈現(xiàn)的截止時(shí)間。 - SurfaceFlinger:此部分顯示 SurfaceFlinger 處理幀緩沖區(qū)的時(shí)間械念。SurfaceFlinger 是負(fù)責(zé)將緩沖區(qū)內(nèi)容發(fā)送到顯示屏的系統(tǒng)進(jìn)程头朱。
- VSYNC:此部分顯示 VSYNC,這是一個(gè)表示與顯示流水線保持同步的信號龄减。該軌跡會顯示 VSYNC-app 信號项钮,這個(gè)信號會在應(yīng)用啟動時(shí)間過晚時(shí)顯示。通常情況下希停,發(fā)生這種情況是因?yàn)榻缑婢€程處于忙碌狀態(tài)烁巫。在動畫播放期間,它會導(dǎo)致屏幕上出現(xiàn)可見的閃爍宠能,并且在動畫或滾動完成之前亚隙,會持續(xù)帶來額外的輸入延遲。對于刷新率較高的顯示屏违崇,尤其要注意查看該軌跡阿弃,因?yàn)榕c刷新率為 60 次/秒或刷新率可變的顯示屏相比诊霹,這種顯示屏更容易出現(xiàn)此類問題。
-
BufferQueue:此部分顯示有多少幀緩沖區(qū)在排隊(duì)等待 SurfaceFlinger 使用渣淳。對于部署到搭載 Android 9(API 級別 28)或更高版本的設(shè)備的應(yīng)用脾还,此軌跡顯示應(yīng)用 surface BufferQueue 的緩沖區(qū)計(jì)數(shù)(
0
、1
或2
)入愧。BufferQueue 可幫助您了解圖像緩沖區(qū)在 Android 圖形組件之間切換時(shí)的狀態(tài)鄙漏。例如,值2
表示應(yīng)用當(dāng)前處于三重緩沖狀態(tài)砂客,這會導(dǎo)致額外的輸入延遲泥张。
Display 部分會提供有助于檢測潛在卡頓的實(shí)用信號,例如何時(shí)界面線程或 RenderThread
的用時(shí)超過 16 毫秒鞠值。若要調(diào)查導(dǎo)致卡頓的確切細(xì)節(jié)媚创,您可以查看 Threads 部分,其中會顯示與界面呈現(xiàn)有關(guān)的線程彤恶。
在上圖中钞钙,Threads 部分顯示了界面線程 (java.com.google.samples.apps.iosched
)、RenderThread
和 GPU completion
線程声离。這些線程與界面呈現(xiàn)有關(guān)芒炼,可能是導(dǎo)致卡頓的原因。
如需在 Android 10 或更低版本上檢測卡頓情況术徊,請執(zhí)行以下操作:
-
查看 Display 中的 Frames 軌跡本刽。紅色幀是要調(diào)查的候選對象。
-
發(fā)現(xiàn)可能存在卡頓的幀后赠涮,請按
W
子寓,或在按住 <kbd style="box-sizing: inherit;">Control</kbd> 鍵(在 macOS 設(shè)備上,則按住 <kbd style="box-sizing: inherit;">Command</kbd> 鍵)的同時(shí)滾動鼠標(biāo)滾輪笋除,以便進(jìn)行放大斜友。繼續(xù)放大,直到您看到界面線程和RenderThread
中的軌跡事件垃它。
在上圖中鲜屏,
Choreographer#doFrame
顯示了界面線程何時(shí)調(diào)用Choreographer
來協(xié)調(diào)動畫、視圖布局国拇、圖像繪制和相關(guān)進(jìn)程洛史。DrawFrames
顯示了RenderThread
何時(shí)形成并向 GPU 發(fā)出實(shí)際繪制命令。 如果您發(fā)現(xiàn)某個(gè)軌跡事件特別長贝奇,可以進(jìn)一步放大虹菲,以便找出可能導(dǎo)致呈現(xiàn)速度緩慢的原因。上圖顯示了界面線程中的
inflate
掉瞳,這意味著應(yīng)用正在花時(shí)間膨脹布局毕源。當(dāng)您放大其中一個(gè)inflate
事件時(shí),可以確切了解每個(gè)界面組件花費(fèi)的時(shí)間陕习,如下所示霎褐。