Configura un trabajador para la carga de perfiles

ProfilingManager guarda los seguimientos de forma local en el dispositivo. Si bien puedes recuperar estos archivos con ADB para la depuración local, la recopilación de datos de campo requiere que los subas a un servidor.

Los archivos de registro pueden ser grandes (a menudo, de varios MB). Para evitar afectar de forma negativa la experiencia del usuario o consumir datos móviles, debes programar las cargas para que se realicen en segundo plano, preferentemente cuando el dispositivo esté conectado a una red no medida (Wi-Fi), se esté cargando y esté inactivo.

Configura un trabajo de carga de WorkManager

ProfilingManager es independiente de la nube; puedes subir seguimientos a cualquier infraestructura que elijas. En el siguiente ejemplo, se muestra cómo usar WorkManager para programar un trabajo de carga que evite interrupciones para el usuario.

Ejemplo de código para configurar un trabajo de carga

Aquí se incluye un ejemplo de cómo puedes configurar un trabajo que no interrumpa al usuario para subir seguimientos a tu servidor.

Cómo agregar dependencias de WorkManager

Además de las dependencias de ProfilingManager existentes, agrega estas bibliotecas de Jetpack a tu archivo build.gradle.kts. WorkManager los necesita.

Kotlin

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

Groovy

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

Fragmento de código

En este código, se muestra cómo configurar un trabajo para subir seguimientos. El trabajo se debe configurar cuando tu app recibe el ProfilingResult. La sección de generación de perfiles se omite en esta sección, pero puedes encontrar un ejemplo en Cómo registrar un seguimiento 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());
}

Explicación del código

El código hace lo siguiente:

  • Define el trabajador: Crea una clase TraceUploadWorker que extienda Worker. Implementa el método doWork() para controlar la lógica de carga de archivos real con el SDK de backend o el cliente HTTP que prefieras.

  • Generación de perfiles de solicitud: Usa SystemTraceRequestBuilder para configurar el seguimiento (duración, política de búfer) y Profiling.requestProfiling para iniciarlo.

  • Programa el trabajo:

    • Crea un OneTimeWorkRequest para tu trabajador.

    • Establece restricciones: Usa setRequiredNetworkType(NetworkType.UNMETERED), setRequiresDeviceIdle(true) y setRequiresCharging(true) para asegurarte de que la carga solo se realice cuando el usuario esté conectado a Wi-Fi, cargando el dispositivo y no lo esté usando de forma activa. Esto es importante para evitar interrumpir al usuario con el trabajo de carga.

    • Pasa datos: Usa setInputData para pasar la ruta de seguimiento al trabajador.

    • Enqueue: Envía la solicitud a WorkManager llamando a WorkManager#enqueue.

Próximos pasos

Después de subir los seguimientos, puedes analizarlos de forma individual o realizar un análisis de seguimiento masivo. Para obtener orientación sobre cómo configurar una canalización de análisis escalable, consulta Implementa Bigtrace en Kubernetes.