Configurare un worker per il caricamento dei profili

ProfilingManager salva le tracce localmente sul dispositivo. Sebbene sia possibile recuperare questi file utilizzando ADB per il debug locale, la raccolta dei dati sul campo richiede il caricamento su un server.

I file di traccia possono essere di grandi dimensioni (spesso diversi MB). Per evitare di influire negativamente sull'esperienza utente o di consumare dati mobili, devi pianificare i caricamenti in modo che avvengano in background, preferibilmente quando il dispositivo è connesso a una rete senza limiti di dati (Wi-Fi), è in carica ed è inattivo.

Configurare un job di caricamento di WorkManager

ProfilingManager è indipendente dal cloud; puoi caricare le tracce su qualsiasi infrastruttura tu scelga. L'esempio seguente mostra come utilizzare WorkManager per pianificare un job di caricamento che non interrompa l'attività dell'utente.

Esempio di codice per configurare un job di caricamento

Ecco un esempio di come puoi configurare un job che non interrompa l'attività dell'utente per caricare le tracce sul tuo server.

Aggiungere le dipendenze di WorkManager

Oltre alle dipendenze ProfilingManager esistenti, aggiungi queste librerie Jetpack al file build.gradle.kts. WorkManager ne ha bisogno.

Kotlin

   dependencies {
       implementation("androidx.work:work-runtime:2.11.2")
   }
   

Alla moda

   dependencies {
       implementation 'androidx.work:work-runtime:2.11.2'
   }
   

Snippet di codice

Questo codice mostra come configurare un job per il caricamento delle tracce. Il job deve essere configurato quando l'ProfilingResult viene ricevuto dalla tua app. La sezione di profilazione è omessa in questa sezione, ma un esempio è disponibile in Registrare una traccia di sistema.

Kotlin

class TraceUploadWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        // Perform your uploading work here
        Log.d("ProfileTest", "Uploading trace: " + inputData.getString("PROFILE_PATH"))

        return Result.success()
    }
}

fun setupProfileUploadWorker(profileFilepath: String?) {
    val workMgr = WorkManager.getInstance(applicationContext)
    val workRequestBuilder = OneTimeWorkRequest.Builder(TraceUploadWorker::class)

    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.UNMETERED)
        .setRequiresDeviceIdle(true)
        .setRequiresCharging(true)
        .build()
    workRequestBuilder.setConstraints(constraints)

    val inputDataBuilder = Data.Builder()
    inputDataBuilder.putString("PROFILE_PATH", profileFilepath)
    workRequestBuilder.setInputData(inputDataBuilder.build())

    workMgr.enqueue(workRequestBuilder.build())
}

Java

public static class TraceUploadWorker extends Worker {

  public TraceUploadWorker(
      @androidx.annotation.NonNull Context context,
      @androidx.annotation.NonNull WorkerParameters workerParams) {
    super(context, workerParams);
  }

  @androidx.annotation.NonNull
  @Override
  public Result doWork() {
    // Perform your uploading work here
    Log.d("ProfileTest", "Uploading trace: " + getInputData().getString("PROFILE_PATH"));

    return Result.success();
  }
}

public void setupProfileUploadWorker(String profileFilepath) {
  WorkManager workMgr = WorkManager.getInstance(getApplicationContext());
  OneTimeWorkRequest.Builder workRequestBuilder = new OneTimeWorkRequest.Builder(
      TraceUploadWorker.class);

  Constraints constraints = new Constraints.Builder()
      .setRequiredNetworkType(NetworkType.UNMETERED)
      .setRequiresDeviceIdle(true)
      .build();
  workRequestBuilder.setConstraints(constraints);

  Data.Builder inputDataBuilder = new Data.Builder();
  inputDataBuilder.putString("PROFILE_PATH", profileFilepath);
  workRequestBuilder.setInputData(inputDataBuilder.build());

  workMgr.enqueue(workRequestBuilder.build());
}

Procedura dettagliata del codice

Il codice esegue le seguenti operazioni:

  • Definisci il worker: crea una classe TraceUploadWorker che estende Worker. Implementa il metodo doWork() per gestire la logica di caricamento effettiva dei file utilizzando l'SDK backend o il client HTTP che preferisci.

  • Richiedi la profilazione: utilizza SystemTraceRequestBuilder per configurare la traccia (durata, policy del buffer) e Profiling.requestProfiling per avviarla.

  • Pianifica il lavoro:

    • Crea un OneTimeWorkRequest per il tuo worker.

    • Imposta i vincoli: utilizza setRequiredNetworkType(NetworkType.UNMETERED), setRequiresDeviceIdle(true) e setRequiresCharging(true) per assicurarti che il caricamento avvenga solo quando l'utente è connesso al Wi-Fi, il dispositivo è in carica e non è in uso. Questo è importante per evitare di interrompere l'attività dell'utente con il job di caricamento.

    • Trasmetti i dati: utilizza setInputData per trasmettere il percorso della traccia al worker.

    • Accoda: invia la richiesta a WorkManager chiamando WorkManager#enqueue.

Passaggi successivi

Dopo aver caricato le tracce, puoi analizzarle singolarmente o eseguire un'analisi collettiva delle tracce. Per indicazioni sulla configurazione di una pipeline di analisi scalabile, consulta Deployment di Bigtrace su Kubernetes.