Auf dieser Seite wird beschrieben, wie Sie mit der ProfilingManager API einen System-Trace aufzeichnen.
Mit ProfilingManager können auch andere Profiltypen aufgezeichnet werden. Dieser Vorgang ähnelt dem Aufzeichnen eines System-Traces, aber für jeden Typ wird ein anderer Builder verwendet. Die unterstützten Profile und ihre Builder sind:
System-Traces:werden mit
SystemTraceRequestBuilderaufgezeichnet und sind nützlich für die Latenzanalyse und die allgemeine Fehlerbehebung bei der Leistung.Heap-Dumps:werden mit
JavaHeapDumpRequestBuilderaufgezeichnet und sind hilfreich für die Erkennung und Optimierung von Speicherlecks.Heap-Profile: werden mit
HeapProfileRequestBuilderaufgezeichnet und sind nützlich für die Speicheroptimierung.Aufrufstack-Profile:werden mit
StackSamplingRequestBuilderaufgezeichnet und sind nützlich, um die Codeausführung und die Latenz zu analysieren.
Abhängigkeiten hinzufügen
Fügen Sie der Datei build.gradle.kts die folgenden Jetpack-Bibliotheken hinzu, um die ProfilingManager API optimal zu nutzen.
Kotlin
dependencies { implementation("androidx.tracing:tracing:1.3.0") implementation("androidx.core:core:1.18.0") }
Groovy
dependencies { implementation 'androidx.tracing:tracing:1.3.0' implementation 'androidx.core:core:1.18.0' }
System-Trace aufzeichnen
Nachdem Sie die erforderlichen Abhängigkeiten hinzugefügt haben, verwenden Sie den folgenden Code, um einen System-Trace aufzuzeichnen. In diesem Beispiel wird eine grundlegende Einrichtung in einer Activity gezeigt, um eine Profilerstellungssitzung zu starten und zu verwalten.
Kotlin
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) fun sampleRecordSystemTrace() { val mainExecutor: Executor = Dispatchers.IO.asExecutor() // Your choice of executor for the callback to occur on. val resultCallback = Consumer<ProfilingResult> { profilingResult -> if (profilingResult.errorCode == ProfilingResult.ERROR_NONE) { Log.d( "ProfileTest", "Received profiling result file=" + profilingResult.resultFilePath ) } else { Log.e( "ProfileTest", "Profiling failed errorcode=" + profilingResult.errorCode + " errormsg=" + profilingResult.errorMessage ) } } val stopSignal = CancellationSignal() val requestBuilder = SystemTraceRequestBuilder() requestBuilder.setCancellationSignal(stopSignal) requestBuilder.setTag("FOO") // Caller supplied tag for identification requestBuilder.setDurationMs(60000) requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER) requestBuilder.setBufferSizeKb(20971520) requestProfiling(applicationContext, requestBuilder.build(), mainExecutor, resultCallback) // Wait some time for profiling to start. Trace.beginSection("MyApp:HeavyOperation") heavyOperation() Trace.endSection() // Once the interesting code section is profiled, stop profile stopSignal.cancel() } fun heavyOperation() { // Computations you want to profile }
Java
void heavyOperation() { // Computations you want to profile } void sampleRecordSystemTrace() { 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()); } } }; CancellationSignal stopSignal = new CancellationSignal(); SystemTraceRequestBuilder requestBuilder = new SystemTraceRequestBuilder(); requestBuilder.setCancellationSignal(stopSignal); requestBuilder.setTag("FOO"); requestBuilder.setDurationMs(60000); requestBuilder.setBufferFillPolicy(BufferFillPolicy.RING_BUFFER); requestBuilder.setBufferSizeKb(20971520); Profiling.requestProfiling(getApplicationContext(), requestBuilder.build(), mainExecutor, resultCallback); // Wait some time for profiling to start. Trace.beginSection("MyApp:HeavyOperation"); heavyOperation(); Trace.endSection(); // Once the interesting code section is profiled, stop profile stopSignal.cancel(); }
Der Beispielcode richtet die Profilerstellungssitzung ein und verwaltet sie. Dazu werden die folgenden Schritte ausgeführt:
Executor einrichten Erstellen Sie einen
Executor, um den Thread zu definieren, der die Profilerstellungsergebnisse empfängt. Die Profilerstellung erfolgt im Hintergrund. Wenn Sie einen Executor für einen Nicht-UI-Thread verwenden, können Sie ANR-Fehler (App antwortet nicht) vermeiden, wenn Sie dem Callback später weitere Verarbeitung hinzufügen.Profilerstellungsergebnisse verarbeiten Erstellen Sie ein
Consumer<ProfilingResult>-Objekt. Das System verwendet dieses Objekt, um Profilerstellungsergebnisse vonProfilingManageran Ihre App zurückzusenden.Profilerstellungsanfrage erstellen Erstellen Sie einen
SystemTraceRequestBuilder, um Ihre Profilerstellungssitzung einzurichten. Mit diesem Builder können Sie die Trace-Einstellungen vonProfilingManageranpassen. Die Anpassung des Builders ist optional. Andernfalls verwendet das System die Standardeinstellungen.- Tag definieren Verwenden Sie
setTag(), um dem Trace-Namen ein Tag hinzuzufügen. Mit diesem Tag können Sie den Trace identifizieren. - Optional: Dauer festlegen Verwenden Sie
setDurationMs(), um die Dauer der Profilerstellung in Millisekunden anzugeben. Mit60000wird beispielsweise ein 60-Sekunden-Trace festgelegt. Der Trace wird nach der angegebenen Dauer automatisch beendet, wennCancellationSignalnicht vorher ausgelöst wird. - Pufferrichtlinie auswählen Verwenden Sie
setBufferFillPolicy(), um festzulegen, wie Trace-Daten gespeichert werden.BufferFillPolicy.RING_BUFFERbedeutet, dass neue Daten die ältesten Daten überschreiben, wenn der Puffer voll ist. So wird eine kontinuierliche Aufzeichnung der letzten Aktivitäten beibehalten. - Puffergröße festlegen Verwenden Sie
setBufferSizeKb(), um eine Puffergröße für das Tracing anzugeben. Damit können Sie die Größe der Ausgabedatei des Traces steuern.
- Tag definieren Verwenden Sie
Optional: Lebenszyklus der Sitzung verwalten Erstellen Sie ein
CancellationSignal. Mit diesem Objekt können Sie die Profilerstellungssitzung jederzeit beenden und so die Länge genau steuern.Starten und Ergebnisse empfangen Wenn Sie
requestProfiling()aufrufen, startetProfilingManagerim Hintergrund eine Profilerstellungssitzung. Sobald die Profilerstellung abgeschlossen ist, wirdProfilingResultan die MethoderesultCallback#acceptgesendet. Wenn die Profilerstellung erfolgreich abgeschlossen wurde, enthält dieProfilingResultden Pfad, in dem der Trace auf Ihrem Gerät gespeichert wurde überProfilingResult#getResultFilePath. Sie können diese Datei programmatisch oder für die lokale Profilerstellung abrufen, indem Sieadb pull <trace_path>auf Ihrem Computer ausführen.Benutzerdefinierte Trace-Punkte hinzufügen Sie können dem Code Ihrer App benutzerdefinierte Trace-Punkte hinzufügen. Im vorherigen Codebeispiel wird mit
Trace.beginSection()undTrace.endSection()ein Trace-Slice namensMyApp:HeavyOperationhinzugefügt. Dieses benutzerdefinierte Slice wird im generierten Profil angezeigt und hebt bestimmte Vorgänge in Ihrer App hervor.