Auf dieser Seite wird beschrieben, wie Sie mit der ProfilingManager API einen System-Trace aufzeichnen.
Mit ProfilingManager können auch andere Arten von Profilen aufgezeichnet werden. Dieser Vorgang ähnelt dem Aufzeichnen eines System-Traces. Der Hauptunterschied besteht darin, dass Sie je nach benötigtem Profiltyp einen bestimmten Builder aus der folgenden Liste verwenden:
- Heap-Dumps:Mit
JavaHeapDumpRequestBuilderaufgezeichnet, was für die Erkennung und Optimierung von Speicherlecks hilfreich ist. - Heap-Profile:Mit
HeapProfileRequestBuilderaufgezeichnet, was für die Speicheroptimierung nützlich ist. - Callstack-Profile:Sie werden mit
StackSamplingRequestBuilderaufgezeichnet und sind nützlich für das Verständnis und die Latenzanalyse.
Abhängigkeiten hinzufügen
Für eine optimale Nutzung der ProfilingManager API fügen Sie die folgenden Jetpack-Bibliotheken in Ihre build.gradle.kts-Datei ein.
Kotlin
dependencies { implementation("androidx.tracing:tracing:1.3.0") implementation("androidx.core:core:1.17.0") }
Groovy
dependencies { implementation 'androidx.tracing:tracing:1.3.0' implementation 'androidx.core:core:1.17.0' }
System-Trace aufzeichnen
Nachdem Sie die erforderlichen Abhängigkeiten hinzugefügt haben, können Sie mit dem folgenden Code einen System-Trace aufzeichnen. In diesem Beispiel wird eine einfache Einrichtung in einem Activity zum Starten und Verwalten einer Profilerstellungssitzung gezeigt.
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(); }
Im Beispielcode wird die Profilerstellungssitzung durch die folgenden Schritte eingerichtet und verwaltet:
Executor einrichten: Erstellen Sie eine
Executor, um den Thread zu definieren, der die Profilerstellungsergebnisse empfängt. Das Profiling erfolgt im Hintergrund. Wenn Sie einen Executor für einen Thread verwenden, der nicht zur Benutzeroberfläche gehört, können Sie ANR-Fehler (Application Not Responding) vermeiden, falls Sie dem Callback später weitere Verarbeitung hinzufügen.Profiler-Ergebnisse verarbeiten Erstellen Sie ein
Consumer<ProfilingResult>-Objekt. Das System verwendet dieses Objekt, um Profilergebnisse vonProfilingManageran Ihre App zurückzusenden.Profilanfrage erstellen Erstellen Sie eine
SystemTraceRequestBuilder, um die Profilerstellungssitzung einzurichten. Mit diesem Builder können Sie dieProfilingManager-Trace-Einstellungen anpassen. Das Anpassen des Builders ist optional. Andernfalls verwendet das System Standardeinstellungen.- Tag definieren Mit
setTag()können Sie dem Namen des Traces ein Tag hinzufügen. Mit diesem Tag können Sie den Trace identifizieren. - Optional: Dauer festlegen Mit
setDurationMs()können Sie angeben, wie lange das Profiling in Millisekunden dauern soll. Mit60000wird beispielsweise ein 60-Sekunden-Trace festgelegt. Die Aufzeichnung wird nach der angegebenen Dauer automatisch beendet, wennCancellationSignalnicht vorher ausgelöst wird. - Pufferrichtlinie auswählen Mit
setBufferFillPolicy()können Sie festlegen, wie Tracedaten gespeichert werden.BufferFillPolicy.RING_BUFFERbedeutet, dass neue Daten die ältesten Daten überschreiben, wenn der Puffer voll ist. So wird ein kontinuierlicher Datensatz der letzten Aktivitäten erstellt. - Zwischenspeichergröße festlegen Mit
setBufferSizeKb()können Sie eine Puffergröße für das Tracing angeben, mit der Sie die Größe der Ausgabetracedatei steuern können.
- Tag definieren Mit
Optional: Sitzungslebenszyklus 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 erhalten Wenn Sie
requestProfiling()anrufen, startetProfilingManagerim Hintergrund eine Profilerstellungssitzung. Nach dem Profiling wirdProfilingResultan IhreresultCallback#accept-Methode gesendet. Wenn das Profiling erfolgreich abgeschlossen wurde, gibtProfilingResultden Pfad an, unter dem der Trace auf Ihrem Gerät überProfilingResult#getResultFilePathgespeichert wurde. Sie können diese Datei programmatisch oder für das lokale Profiling durch Ausführen vonadb pull <trace_path>auf Ihrem Computer abrufen.Benutzerdefinierte Trace-Punkte hinzufügen Sie können benutzerdefinierte Trace-Punkte im Code Ihrer App hinzufügen. Im vorherigen Codebeispiel wird mit
Trace.beginSection()undTrace.endSection()ein Trace-Segment mit dem NamenMyApp:HeavyOperationhinzugefügt. Dieser benutzerdefinierte Slice wird im generierten Profil angezeigt und hebt bestimmte Vorgänge in Ihrer App hervor.