卡頓 (名詞): 指應用性能糟糕,可能導致丟幀、界面動畫不連貫和用戶體驗不佳等問題。請參閱 "不開心的用戶" 詞條。
性能問題很難調試。我們常常不清楚要從何下手、使用何種工具、用戶遇到了什么問題,以及那些問題在現實的設備上有何表現。
過去幾年間,Android 團隊一直努力推出更多工具,用于調試各種問題,從分析啟動性能到測試具體代碼路徑,再到測試和優化特定用例及 IDE 中的可視化分析器,各領域均有涉獵。所有這些工具均針對開發期間的測試設計,用于幫助您調試和修復在本地運行時發現的問題。
同時,Google Play 的 Android Vitals 和 Firebase 均提供信息中心,供開發者了解其應用在實際用戶設備上的運行情況。
盡管如此,在實際情況中,我們仍然很難發現應用中可能存在的問題,尤其是用戶設備上可能出現的問題。這可不是您坐在座椅中用著熟悉的開發機器能碰到的問題。雖說性能信息中心可提供一定幫助,但在用戶遇到問題時,它卻未必能讓您充分了解所發生情況的詳細信息。
JankStats 應運而生: 這是首個專為在用戶設備上檢測及報告應用的性能問題而構建的 AndroidX 庫。
JankStats 是占用空間相對較小的 API,主要有三大目標: 捕獲每幀的性能信息、在用戶設備 (不僅是開發設備) 上運行、以及在應用出現性能問題時啟用檢測,并報告所發生的情況。
每幀性能
Android 平臺已提供多種方法,用于獲取幀性能數據。例如,從 API 24 開始就可以使用 FrameMetrics 獲取相關數據,后續多個版本也在進一步豐富該功能,以便為您提供更多詳細信息。如果在更早期的版本上運行應用,也有多種方法可供您獲取時間信息,雖說不夠準確,但仍十分實用。
因此,如果您想確保自己的幀持續時間邏輯適用于所有版本,就需要在不同的 API 版本中實現不同的測試和報告機制。現在,您可以使用統一的 JankStats API 來實現這些功能。除此之外,它還提供了更多驚喜 (請繼續閱讀本文!)。
JankStats 通過提供單一 API 來報告每幀的時間,從而簡化您的工作,并會在內部委派適當機制 (比如 API 24 以上會委派給 FrameMetrics)。您不必關心這些數據的來源,只需讓 JankStats 告訴您完成特定事項花費的時間,然后便可在回調中獲取相關信息。
創建和監聽 JankStats 數據就是這么簡單: 只需完成創建,然后就可以坐下來 (好吧,是您的代碼 "坐" 下來) 監聽。以下是 JankStats 的示例 JankLoggingActivity 中的步驟范例:
val jankFrameListener = JankStats.OnFrameListener { frameData ->
// real app would do something more interesting than log this...
Log.v("JankStatsSample", frameData.toString())
}
jankStats = JankStats.createAndTrack(
window,
Dispatchers.Default.asExecutor(),
jankFrameListener,
)
此處的 Log.v() 調用僅作范例使用,并非您在應用中應采取的操作。在實際操作中,您可能應匯整/儲存/上傳數據,以供日后分析使用,而非將數據發布于日志中。無論如何,下面是在 API 30 模擬器上運行時產生的輸出示例 (為便于閱讀,已刪除部分 logcat 的輸出內容,并添加了空白行):
JankStats.OnFrameListener: FrameData(frameStartNanos=827233150542009,frameDurationUiNanos=27779985,frameDurationCpuNanos=31296985,isJank=false,states=[Activity:JankLoggingActivity])
JankStats.OnFrameListener: FrameData(frameStartNanos=827314067288736, frameDurationUiNanos=89903592, frameDurationCpuNanos=94582592, isJank=true, states=[RecyclerView: Dragging, Activity: JankLoggingActivity])
JankStats.OnFrameListener: FrameData(frameStartNanos=827314167288732, frameDurationUiNanos=88641926, frameDurationCpuNanos=91526926, isJank=true, states=[RecyclerView: Settling, RecyclerView: Dragging, Activity: JankLoggingActivity])
JankStats.OnFrameListener: FrameData(frameStartNanos=827314183945923, frameDurationUiNanos=4731405, frameDurationCpuNanos=8283405, isJank=false, states=[RecyclerView: Settling, Activity: JankLoggingActivity])
您可以在日志的 frameData 中看到一些有趣的內容:
其中有部分幀帶有 isJank=true 標記。該日志取自運行的示例應用 JankLoggingActivity,您可查看完整示例了解更多。該應用會強制產生一些長幀 (沒錯,用了 Thread.sleep()!),從而讓 JankStats 判定其為卡頓。
幀的時間信息中同時包含界面和 CPU 數據,但在 API 24 (FrameMetrics 被引入的版本) 之前的版本中,此信息僅包含界面持續時間。
該日志是從我在應用中開始滑動 RecyclerView 時獲取的。當 RecyclerView 開始移動 (被 "拖動") 以及 RecyclerView 開始自由滾動 (被 "放置") 時,我們可在開始之前看到與界面狀態相關的信息 (僅列出 Activity 狀態)。有關這些界面狀態的詳細信息,請閱讀下文。
真實數據
不同于最近的基準庫,創建 JankStats 的目的是為您提供來自用戶設備的結果。能在開發機器上調試問題固然很好,但在現實中,用戶會根據迥異的約束條件,在不同的設備上使用您的應用,對于這類情況,本地調試可能并不能發現和解決問題。
JankStats 提供 API 來檢測您的應用,以提供您所需的性能數據和報告機制,以便您能上傳這些數據并離線進行分析。
應用狀態
最后 (請注意,這才是 JankStats 庫的新亮點),JankStats 提供了一種方法,可讓您了解出現性能問題時應用中實際發生的情況。我們經常聽到的抱怨是: 現有的工具、信息中心和方法均未能提供足夠的背景信息,不足以讓您知曉用戶實際遭遇到的性能問題。
例如,FrameMetrics API (在 API 24 版本中推出,JankStats 內部也有使用) 可以告訴您繪制幀需要多長時間,而您也可從中獲取卡頓信息,但它無法讓您知曉當時應用中的具體情況。當您嘗試檢測代碼,并將其與 FrameMetrics 或其他性能測量工具集成時,該問題就需要開發者自行解決。但是,除非必須要在內部構建這種基礎架構,那每個人都有許多別的工作要做。因此,卡頓問題通常得不到量化測試,而性能問題自然也無法解決。
同樣,Android Vitals 信息中心也可以告訴您,應用存在性能問題,但無法告訴您問題發生時應用的具體運行情況。因此,您很難通過這些信息來知曉應該如何處理出現的問題。
JankStats 推出了 PerformanceMetricsState API,這套簡單的方法可讓您通過成對的字符串告訴系統在任意時刻您的應用所發生的事情。例如,您可能想知道,某個特定的 Activity 或 Fragment 在何時處于活動狀態,或 RecyclerView 何時處于滾動狀態。
例如,下面是 JankStats 示例中的代碼,表明該工具如何檢測 RecyclerView,以向 JankStats 提供此信息:
val scrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView,
newState: Int)
{
val metricsState = metricsStateHolder?.state ?: return
when (newState) {
RecyclerView.SCROLL_STATE_DRAGGING -> {
metricsState.addState("RecyclerView", "Dragging")
}
RecyclerView.SCROLL_STATE_SETTLING -> {
metricsState.addState("RecyclerView", "Settling")
}
else -> {
metricsState.removeState("RecyclerView")
}
}
}
}
此狀態可在您應用中的任何地方 (甚至從其他庫) 注入,當其報告結果時,會被 JankStats 接收到。這樣一來,當您從 JankStats 獲取報告時,不僅可以知道每幀里各種事件花費的時間,還可以了解用戶在那一幀期間做了什么,這可能會是相當有用的信息。
資源
下面這些資源可以幫助您了解有關 JankStats 的更多信息:
AndroidX 項目: JankStats 位于 AndroidX 的 androidx.metrics 庫中:
文檔: 開發者網站提供了新的開發者指南,其中介紹了 JankStats 的用法:
示例代碼: 示例項目展示了如何將 JankStats 對象實例化并進行偵聽,以及如何針對重要的界面狀態信息來監測應用:
錯誤報告: 若您對該庫有任何疑問,或是想提出 API 需求,歡迎向我們提交錯誤報告:
Alpha -> 1.0
JankStats 剛剛發布了首個 alpha 版本,這次發布的用意是: "我們認為這個 API 和功能會對 1.0 版本的發布頗有幫助,請先試用,并和我們分享您的反饋。"
今后我們還想針對 JankStats 做其他事情,包括添加某種聚合機制,甚至與現有的上傳服務同步。不過,在推出首個版本之前,我們希望了解大家的使用情況,以及搜集大家想要的其他功能。我們希望這一版本在當前的基本狀態下能對大家有所幫助。僅僅是輕松檢測并記錄界面狀態信息這個功能,應該就可以為大家提供一些便利。
現在就請大家獲取并試用此版本,我們恭候大家提出的反饋。最重要的是,我們希望大家能借助 JankStats 找出并修復性能問題!您的用戶正等著您呢,別讓他們等太久了!
鍵盤、手寫筆、鼠標、游戲手柄或其他外接設備。如果您想提高應用在這些情況下的易用性,可以計劃支持其中一些輸入方式,如需了解更多詳情,請參閱文章:是時候為各式設備適配完善的輸入支持
除了通過觸摸進行交互外,大屏幕設備還支持其他交互形式。設備的屏幕尺寸
原文標題:JankStats 推出 alpha 版本
文章出處:【微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
審核編輯:湯梓紅
-
測試
+關注
關注
8文章
5360瀏覽量
126873 -
設備
+關注
關注
2文章
4533瀏覽量
70771 -
可視化
+關注
關注
1文章
1198瀏覽量
20994
原文標題:JankStats 推出 alpha 版本
文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論