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註冊觸發條件清單。 - Fire event:呼叫
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
如要進一步瞭解如何以視覺化方式呈現這些追蹤記錄,請參閱「擷取及分析剖析資料」。
背景追蹤的運作方式
為了擷取觸發條件之前的資料,OS 會定期啟動背景追蹤。如果背景追蹤記錄處於啟用狀態,且應用程式已註冊,則觸發事件發生時,系統會將追蹤記錄設定檔儲存至應用程式的目錄。設定檔就會包含觸發前發生的資訊。
設定檔儲存後,系統會使用提供給 registerForAllProfilingResults 的回呼通知應用程式。這個回呼會提供擷取設定檔的路徑,您可以呼叫 ProfilingResult#getResultFilePath() 來存取。
為減少對裝置效能和電池續航力的影響,系統不會持續執行背景追蹤。而是採用取樣方法。系統會在設定的時間範圍內 (有最短和最長持續時間),隨機啟動背景追蹤。隨機間隔這些追蹤記錄可提高觸發條件涵蓋率。
系統觸發的設定檔有系統定義的大小上限,因此會使用環狀緩衝區。緩衝區滿了之後,新的追蹤記錄資料會覆寫最舊的資料。如圖 1 所示,如果緩衝區已滿,擷取的追蹤記錄可能不會涵蓋背景錄製的整個時間長度,而是代表觸發前最近的活動。
實施觸發條件專屬的頻率限制
高頻率觸發條件可能會快速消耗應用程式的頻率限制器配額。如要進一步瞭解頻率限制器,建議您參閱「頻率限制器的運作方式」。為避免單一觸發條件類型耗盡配額,您可以實施觸發條件專屬的頻率限制。
ProfilingManager 支援應用程式定義的觸發條件專屬頻率限制。除了現有的頻率限制器外,您還可以新增另一層時間限制。使用 setRateLimitingPeriodHours API 設定觸發條件的特定冷卻時間。冷卻時間結束後,即可再次觸發。
在本機偵錯觸發條件
由於背景追蹤會在隨機時間執行,因此在本機偵錯觸發條件相當困難。如要強制執行背景追蹤記錄進行測試,請使用下列 ADB 指令:
adb shell device_config put profiling_testing system_triggered_profiling.testing_package_name <com.example.myapp>
這個指令會強制系統針對指定套件啟動連續背景追蹤,讓每個觸發條件都能在頻率限制器允許的情況下收集設定檔。
您也可以啟用其他偵錯選項,例如在本機偵錯時停用頻率限制器。詳情請參閱「本機剖析的偵錯指令」。