Configurar um worker para upload de perfil

O ProfilingManager salva rastreamentos localmente no dispositivo. Embora seja possível recuperar esses arquivos usando o ADB para depuração local, a coleta de dados de campo exige o upload deles para um servidor.

Os arquivos de rastreamento podem ser grandes (geralmente vários MBs). Para evitar afetar negativamente a experiência do usuário ou consumir dados móveis, programe os uploads para ocorrerem em segundo plano, de preferência quando o dispositivo estiver em uma rede ilimitada (Wi-Fi), carregando e inativo.

Configurar um job de upload do WorkManager

O ProfilingManager é independente da nuvem. É possível fazer upload de rastreamentos para qualquer infraestrutura que você escolher. O exemplo a seguir demonstra como usar WorkManager para programar um job de upload que evite interrupções para o usuário.

Exemplo de código para configurar um job de upload

Confira um exemplo de como configurar um job que não seja disruptivo para o usuário para fazer upload de rastreamentos para seu servidor.

Adicionar dependências do WorkManager

Além das dependências ProfilingManager atuais, adicione estas bibliotecas do Jetpack ao arquivo build.gradle.kts. WorkManager precisa deles.

Kotlin

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

Groovy

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

Snippet de código

Este código mostra como configurar um job para fazer upload de rastreamentos. O job precisa ser configurado quando o ProfilingResult é recebido pelo app. A seção de criação de perfil é omitida nesta seção, mas um exemplo pode ser encontrado em Gravar um rastreamento do 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());
}

Tutorial do código

O código faz o seguinte:

  • Defina o worker: crie uma classe TraceUploadWorker que estenda Worker. Implemente o método doWork() para processar a lógica de upload de arquivos usando o SDK de back-end ou o cliente HTTP de sua preferência.

  • Criação de perfil de solicitações: use SystemTraceRequestBuilder para configurar o rastreamento (duração, política de buffer) e Profiling.requestProfiling para iniciar o processo.

  • Programe o trabalho:

    • Crie um OneTimeWorkRequest para seu worker.

    • Defina restrições: use setRequiredNetworkType(NetworkType.UNMETERED), setRequiresDeviceIdle(true) e setRequiresCharging(true) para garantir que o upload só aconteça quando o usuário estiver conectado ao Wi-Fi, carregando e não usando o dispositivo ativamente. Isso é importante para evitar interrupções no trabalho de upload do usuário.

    • Transmitir dados: use setInputData para transmitir o caminho do rastreamento ao worker.

    • Colocar na fila: envie a solicitação ao WorkManager chamando WorkManager#enqueue.

A seguir

Depois de fazer upload dos rastros, é possível analisá-los individualmente ou realizar uma análise em massa. Para orientações sobre como configurar um pipeline de análise escalonável, consulte Como implantar o Bigtrace no Kubernetes.