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 vengano eseguiti in background, preferibilmente quando il dispositivo è connesso a una rete non a consumo (Wi-Fi), è in carica e non è in uso.

Configura un job di caricamento WorkManager

ProfilingManager è indipendente dal cloud; puoi caricare le tracce in qualsiasi infrastruttura tu scelga. L'esempio seguente mostra come utilizzare WorkManager per pianificare un job di caricamento che eviti interruzioni per l'utente.

Esempio di codice per configurare un job di caricamento

Ecco un esempio di come puoi configurare un job che non interferisca con l'utente per caricare le tracce sul tuo server.

Aggiungi 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.12.0")
   }
   

Alla moda

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

Snippet di codice

Questo codice mostra come configurare un job per il caricamento delle tracce. Il job deve essere configurato quando l'app riceve ProfilingResult. La sezione relativa alla profilazione viene omessa in questa sezione, ma un esempio è disponibile in Registra un tracciamento del 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 queste operazioni:

  • Definisci il worker: crea una classe TraceUploadWorker che estende Worker. Implementa il metodo doWork() per gestire la logica di caricamento dei file effettiva utilizzando l'SDK di 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, in carica e non utilizza attivamente il dispositivo. Questo è importante per evitare interruzioni per l'utente con il job di caricamento.

    • Passa i dati: utilizza setInputData per passare il percorso della traccia al worker.

    • Metti in coda: invia la richiesta a WorkManager chiamando WorkManager#enqueue.

Passaggi successivi

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