Cómo enviar una solicitud simple

Aprende a usar la Biblioteca de Cronet para realizar operaciones de red en tu app de Android. Cronet es la pila de red de Chromium que está disponible como biblioteca para que uses en tus apps. Para obtener más información sobre las funciones de la biblioteca, consulta Cómo realizar operaciones de red con Cronet.

Cómo configurar la biblioteca en tu proyecto

Sigue estos pasos para agregar una dependencia a la Biblioteca de Cronet en tu proyecto:

  1. Verifica que Android Studio incluya una referencia al repositorio Maven de Google en el archivo build.gradle de nivel superior de tu proyecto, como se muestra en el siguiente ejemplo:

    allprojects {
            repositories {
                ...
                google()
            }
        }
        
  2. Incluye una referencia a la Biblioteca de cliente de Servicios de Google Play para Cronet en la sección dependencies del archivo build.gradle del módulo de tu app, como se muestra en el siguiente ejemplo:

    dependencies {
            implementation 'com.google.android.gms:play-services-cronet:16.0.0'
        }
        

    Los objetos CronetEngine que se creen una vez que se agregue esta dependencia usarán Cronet cargado desde los Servicios de Google Play. Llama a CronetProviderInstaller.installProvider(Context) antes de crear objetos CronetEngine para evitar que se generen excepciones inesperadas durante la creación de CronetEngine debido a errores, como dispositivos que requieren una versión actualizada de los Servicios de Google Play.

    En los casos en los que no se puede cargar Cronet desde los Servicios de Google Play, se puede usar una implementación menos eficaz de la API de Cronet. Para usar esta implementación alternativa, tienes que depender de org.chromium.net:cronet-fallback y llamar a new JavaCronetProvider(context).createBuilder().

Cómo crear una solicitud de red

Esta sección te muestra cómo crear y enviar una solicitud de red mediante la Biblioteca de Cronet. Una vez enviada la solicitud de red, tu app debería procesar la respuesta de la red.

Cómo crear y configurar una instancia de CronetEngine

La biblioteca proporciona una clase CronetEngine.Builder que puedes usar para crear una instancia de CronetEngine. En el siguiente ejemplo, se muestra cómo crear un objeto CronetEngine:

Kotlin

    val myBuilder = CronetEngine.Builder(context)
    val cronetEngine: CronetEngine = myBuilder.build()
    

Java

    CronetEngine.Builder myBuilder = new CronetEngine.Builder(context);
    CronetEngine cronetEngine = myBuilder.build();
    

Puedes usar la clase Builder para configurar un objeto CronetEngine. Por ejemplo, puedes proporcionar opciones, como el almacenamiento en caché y la compresión de datos. Para obtener más información, consulta CronetEngine.Builder.

Cómo proporcionar una implementación de la devolución de llamada de la solicitud

Para proporcionar una implementación de la llamada, crea una subclase de UrlRequest.Callback e implementa los métodos abstractos requeridos, como se muestra en el siguiente ejemplo:

Kotlin

    private const val TAG = "MyUrlRequestCallback"

    class MyUrlRequestCallback : UrlRequest.Callback() {
        override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
            Log.i(TAG, "onRedirectReceived method called.")
            // You should call the request.followRedirect() method to continue
            // processing the request.
            request?.followRedirect()
        }

        override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
            Log.i(TAG, "onResponseStarted method called.")
            // You should call the request.read() method before the request can be
            // further processed. The following instruction provides a ByteBuffer object
            // with a capacity of 102400 bytes to the read() method.
            request?.read(ByteBuffer.allocateDirect(102400))
        }

        override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
            Log.i(TAG, "onReadCompleted method called.")
            // You should keep reading the request until there's no more data.
            request?.read(ByteBuffer.allocateDirect(102400))
        }

        override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
            Log.i(TAG, "onSucceeded method called.")
        }
    }
    

Java

    class MyUrlRequestCallback extends UrlRequest.Callback {
      private static final String TAG = "MyUrlRequestCallback";

      @Override
      public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
        Log.i(TAG, "onRedirectReceived method called.");
        // You should call the request.followRedirect() method to continue
        // processing the request.
        request.followRedirect();
      }

      @Override
      public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
        Log.i(TAG, "onResponseStarted method called.");
        // You should call the request.read() method before the request can be
        // further processed. The following instruction provides a ByteBuffer object
        // with a capacity of 102400 bytes to the read() method.
        request.read(ByteBuffer.allocateDirect(102400));
      }

      @Override
      public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
        Log.i(TAG, "onReadCompleted method called.");
        // You should keep reading the request until there's no more data.
        request.read(ByteBuffer.allocateDirect(102400));
      }

      @Override
      public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
        Log.i(TAG, "onSucceeded method called.");
      }
    }
    

Cómo crear un objeto Ejecutor para administrar las tareas de red

Puedes usar la clase Executor para ejecutar tareas de red. Para obtener una instancia de Executor, usa uno de los métodos estáticos de la clase Executors que devuelve un objeto Executor. En el siguiente ejemplo, se muestra cómo crear un objeto Executor con el método newSingleThreadExecutor():

Kotlin

    val executor: Executor = Executors.newSingleThreadExecutor()
    

Java

    Executor executor = Executors.newSingleThreadExecutor();
    

Cómo crear y configurar un objeto UrlRequest

Para crear la solicitud de red, llama al método newUrlRequestBuilder() del CronetEngine pasando la URL de destino, una instancia de tu clase de devolución de llamada y el objeto ejecutor. El método newUrlRequestBuilder() devuelve un objeto UrlRequest.Builder que puedes usar para crear el objeto UrlRequest, como se muestra en el siguiente ejemplo:

Kotlin

    val requestBuilder = cronetEngine.newUrlRequestBuilder(
            "https://www.example.com",
            MyUrlRequestCallback(),
            executor
    )

    val request: UrlRequest = requestBuilder.build()
    

Java

    UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder(
            "https://www.example.com", new MyUrlRequestCallback(), executor);

    UrlRequest request = requestBuilder.build();
    

Puedes usar la clase Builder para configurar la instancia de UrlRequest. Por ejemplo, puedes especificar una prioridad o el verbo HTTP. Para obtener más información, consulta UrlRequest.Builder.

Para iniciar la tarea de red, llama al método start() de la solicitud:

Kotlin

    request.start()
    

Java

    request.start();
    

Si sigues las instrucciones descritas en esta sección, puedes crear y enviar una solicitud de red con Cronet. Sin embargo, para mayor simplicidad, la implementación de ejemplo de UrlRequest.Callback solo imprime un mensaje en el registro. La siguiente sección te muestra cómo suministrar una implementación de devolución de llamada que sea compatible con escenarios más útiles, como extraer datos de la respuesta y detectar un error en la solicitud.

Cómo procesar la respuesta de la red

Una vez que llamas al método start(), se inicia el ciclo de vida de la solicitud de Cronet. Tu app debe gestionar la solicitud durante el ciclo de vida especificando una devolución de llamada. Para obtener más información sobre el ciclo de vida, consulta Ciclo de vida de la solicitud de Cronet. Para especificar una devolución de llamada, crea una subclase de UrlRequest.Callback e implementa los siguientes métodos:

onRedirectReceived()

Se invoca cuando el servidor emite un código de redireccionamiento HTTP en respuesta a la solicitud original. Para seguir el redireccionamiento al nuevo destino, usa el método followRedirect(). De lo contrario, utiliza el método cancel(). En el siguiente ejemplo, se muestra cómo implementar el método:

Kotlin

    override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
      // Determine whether you want to follow the redirect.
      ...

      if (shouldFollow) {
          request?.followRedirect()
      } else {
          request?.cancel()
      }
    }
    

Java

    @Override
    public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
      // Determine whether you want to follow the redirect.
      …

      if (shouldFollow) {
        request.followRedirect();
      } else {
        request.cancel();
      }
    }
    
onResponseStarted()

Se invoca cuando se recibe el conjunto final de encabezados. Solo se invoca el método onResponseStarted() después de seguir todos los redireccionamientos. El siguiente código muestra un ejemplo de implementación del método:

Kotlin

    override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
      val httpStatusCode = info?.httpStatusCode
      if (httpStatusCode == 200) {
        // The request was fulfilled. Start reading the response.
        request?.read(myBuffer)
      } else if (httpStatusCode == 503) {
        // The service is unavailable. You should still check if the request
        // contains some data.
        request?.read(myBuffer)
      }
      responseHeaders = info?.allHeaders
    }
    

Java

    @Override
    public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
      int httpStatusCode = info.getHttpStatusCode();
      if (httpStatusCode == 200) {
        // The request was fulfilled. Start reading the response.
        request.read(myBuffer);
      } else if (httpStatusCode == 503) {
        // The service is unavailable. You should still check if the request
        // contains some data.
        request.read(myBuffer);
      }
      responseHeaders = info.getAllHeaders();
    }
    
onReadCompleted()

Se invoca cada vez que se ha leído parte del cuerpo de la respuesta. El siguiente ejemplo de código muestra cómo implementar el método y extraer el cuerpo de la respuesta:

Kotlin

    override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
      // The response body is available, process byteBuffer.
      ...

      // Continue reading the response body by reusing the same buffer
      // until the response has been completed.
      byteBuffer?.clear()
      request?.read(myBuffer)
    }
    

Java

    @Override
    public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
      // The response body is available, process byteBuffer.
      …

      // Continue reading the response body by reusing the same buffer
      // until the response has been completed.
      byteBuffer.clear();
      request.read(myBuffer);
    }
    
onSucceeded()

Se invoca cuando la solicitud de red se completa correctamente. El siguiente ejemplo muestra cómo implementar el método:

Kotlin

    override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
        // The request has completed successfully.
    }
    

Java

    @Override
    public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
      // The request has completed successfully.
    }
    
onFailed()

Se invoca si la solicitud falla por algún motivo después de llamar al método start(). El siguiente ejemplo muestra cómo implementar el método y obtener información sobre el error:

Kotlin

    override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
        // The request has failed. If possible, handle the error.
        Log.e(TAG, "The request failed.", error)
    }
    

Java

    @Override
    public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
      // The request has failed. If possible, handle the error.
      Log.e(TAG, "The request failed.", error);
    }
    
onCanceled()

Se invoca si la solicitud se canceló utilizando el método cancel(). Una vez que se invoca, no se invoca ningún otro método de la clase UrlRequest.Callback. Puedes usar este método si quieres liberar recursos asignados para procesar una solicitud. En el siguiente ejemplo, se muestra cómo implementar el método:

Kotlin

    override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
        // Free resources allocated to process this request.
        ...
    }
    

Java

    @Override
    public void onCanceled(UrlRequest request, UrlResponseInfo info) {
      // Free resources allocated to process this request.
      …
    }