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 envios 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 o 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.0")
   }
   

Groovy

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

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 estiver 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.