ProfilingManager 支援根據系統觸發條件擷取設定檔。系統會管理記錄程序,並將產生的設定檔提供給應用程式。
觸發條件與效能關鍵事件相關聯。系統記錄的設定檔會提供與這些觸發程序相關聯的關鍵使用者歷程 (CUJ) 詳細偵錯資訊。
擷取歷來資料
許多觸發條件都需要分析事件發生前的歷史資料。觸發條件本身通常是問題的後果,而非根本原因。如果觸發條件發生後才開始剖析,可能已經找不到根本原因。
舉例來說,如果 UI 執行緒上的作業執行時間過長,就會導致應用程式無回應 (ANR) 錯誤。系統偵測到 ANR 並向應用程式發出信號時,作業可能已完成。如果在這個時間點啟動設定檔,就會錯過實際的封鎖作業。
無法準確預測某些觸發條件的發生時間,因此無法預先手動啟動設定檔。
為何要使用觸發條件式擷取?
使用剖析觸發條件的主要原因是,擷取無法預測事件的資料,因為應用程式無法在這些事件發生前手動開始記錄。剖析觸發條件可用於:
- 偵錯效能問題:診斷 ANR、記憶體流失和其他穩定性問題。
- 改善關鍵使用者歷程:分析並改善流程,例如應用程式啟動。
- 瞭解使用者行為:深入瞭解事件,例如使用者主動結束應用程式。
設定觸發條件
下列程式碼示範如何註冊 TRIGGER_TYPE_APP_FULLY_DRAWN 觸發條件,並對其套用頻率限制。
Kotlin
fun recordWithTrigger() { val profilingManager = applicationContext.getSystemService(ProfilingManager::class.java) val triggers = ArrayList<ProfilingTrigger>() val triggerBuilder = ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN) .setRateLimitingPeriodHours(1) triggers.add(triggerBuilder.build()) val mainExecutor: Executor = Executors.newSingleThreadExecutor() val resultCallback = Consumer<ProfilingResult> { profilingResult -> if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.resultFilePath ) setupProfileUploadWorker(profilingResult.resultFilePath) } else { Log.e( "ProfileTest", "Profiling failed errorcode=" + profilingResult.errorCode + " errormsg=" + profilingResult.errorMessage ) } } profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback) profilingManager.addProfilingTriggers(triggers)
Java
public void recordWithTrigger() { ProfilingManager profilingManager = getApplicationContext().getSystemService( ProfilingManager.class); List<ProfilingTrigger> triggers = new ArrayList<>(); ProfilingTrigger.Builder triggerBuilder = new ProfilingTrigger.Builder( ProfilingTrigger.TRIGGER_TYPE_APP_FULLY_DRAWN); triggerBuilder.setRateLimitingPeriodHours(1); triggers.add(triggerBuilder.build()); Executor mainExecutor = Executors.newSingleThreadExecutor(); Consumer<ProfilingResult> resultCallback = new Consumer<ProfilingResult>() { @Override public void accept(ProfilingResult profilingResult) { if (profilingResult.getErrorCode() == ProfilingResult.ERROR_NONE) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.getResultFilePath()); setupProfileUploadWorker(profilingResult.getResultFilePath()); } else { Log.e( "ProfileTest", "Profiling failed errorcode=" + profilingResult.getErrorCode() + " errormsg=" + profilingResult.getErrorMessage()); } } }; profilingManager.registerForAllProfilingResults(mainExecutor, resultCallback); profilingManager.addProfilingTriggers(triggers);
程式碼會執行下列步驟:
- 取得管理員:擷取
ProfilingManager服務。 - 定義觸發條件:為
TRIGGER_TYPE_APP_FULLY_DRAWN建構ProfilingTrigger。應用程式回報已完成啟動並可互動時,就會發生這個事件。 - 設定速率限制:對這個特定觸發條件 (
setRateLimitingPeriodHours(1)) 套用 1 小時的速率限制。這可避免應用程式每小時記錄超過一個啟動設定檔。 - 註冊事件監聽器:呼叫
registerForAllProfilingResults定義處理結果的回呼。這個回呼會透過getResultFilePath()接收已儲存設定檔的路徑。 - 新增觸發條件:使用
addProfilingTriggers向ProfilingManager註冊觸發條件清單。 - 觸發事件:呼叫
reportFullyDrawn(),將TRIGGER_TYPE_APP_FULLY_DRAWN事件傳送至系統,觸發設定檔收集作業 (假設系統背景追蹤正在執行,且有可用的速率限制器配額)。這個選用步驟會示範端對端流程,因為您的應用程式必須呼叫reportFullyDrawn()才能觸發這項功能。
擷取追蹤記錄
系統會將觸發條件設定檔儲存在與其他設定檔相同的目錄中。 觸發的追蹤記錄檔案名稱格式如下:
profile_trigger_<profile_type_code>_<datetime>.<profile-type-name>
您可以使用 ADB 提取檔案。舉例來說,如要使用 ADB 擷取範例程式碼擷取的系統追蹤記錄,程式碼可能如下所示:
adb pull /data/user/0/com.example.sampleapp/files/profiling/profile_trigger_1_2025-05-06-14-12-40.perfetto-trace
如要進一步瞭解如何以視覺化方式呈現這些追蹤記錄,請參閱「擷取及分析剖析資料」。
背景追蹤功能的運作方式
如要擷取觸發事件發生前的資料,作業系統會定期啟動背景追蹤。如果觸發條件在背景追蹤記錄處於啟用狀態時發生,且應用程式已註冊該觸發條件,系統就會將追蹤記錄設定檔儲存至應用程式的目錄。然後,設定檔會包含導致觸發事件的資訊。
設定檔儲存完畢後,系統會使用提供給 registerForAllProfilingResults 的回呼通知應用程式。這個回呼會提供擷取設定檔的路徑,您可以呼叫 ProfilingResult#getResultFilePath() 存取該路徑。
為減少對裝置效能和電池續航力的影響,系統不會持續執行背景追蹤。而是採用抽樣方法。系統會在設定的時間範圍內隨機啟動背景追蹤 (有最短和最長的時間限制)。隨機間隔這些追蹤記錄可提高觸發涵蓋率。
系統觸發的設定檔有系統定義的大小上限,因此會使用環形緩衝區。緩衝區填滿後,新的追蹤資料會覆寫最舊的資料。如圖 1 所示,如果緩衝區已滿,擷取的追蹤記錄可能不會涵蓋整個背景錄製時間,而是代表觸發事件發生前最近的活動。
導入觸發條件專屬的頻率限制
高頻率觸發程序可能會快速耗盡應用程式的速率限制器配額。如要進一步瞭解速率限制器,建議您參閱「速率限制器的運作方式」。如要避免單一觸發條件類型耗盡配額,可以實作觸發條件專屬的頻率限制。
ProfilingManager 支援應用程式定義的觸發條件專屬頻率限制。除了現有的速率限制器,您還可新增另一層以時間為準的節流機制。使用 setRateLimitingPeriodHours API 為觸發條件設定特定冷卻時間。冷卻時間結束後,即可再次觸發。
在本機偵錯觸發條件
由於背景追蹤會在隨機時間執行,因此很難在本機觸發偵錯。如要強制執行背景追蹤以進行測試,請使用下列 ADB 指令:
adb shell device_config put profiling_testing system_triggered_profiling.testing_package_name <com.example.myapp>
這個指令會強制系統為指定套件啟動連續背景追蹤,讓每個觸發程序都能在速率限制器允許的情況下收集設定檔。
您也可以啟用其他偵錯選項,例如在本機偵錯時停用速率限制器。詳情請參閱「本機剖析的偵錯指令」。