Enviar uma solicitação simples

Aprenda a usar a biblioteca Cronet para realizar operações de rede no seu app Android. A Cronet é a pilha de rede do Chromium disponibilizada como uma biblioteca para você usar nos seus apps. Para mais informações sobre os recursos da biblioteca, consulte Realizar operações de rede com a Cronet.

Configurar a biblioteca no projeto

Siga estas etapas para adicionar uma dependência à Biblioteca Cronet no projeto:

  1. Verifique se o Android Studio incluiu uma referência ao repositório Maven do Google no arquivo settings.gradle do projeto, como mostrado no exemplo a seguir:

    Groovy

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }

    Kotlin

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
  2. Inclua uma referência à biblioteca de cliente do Google Play Services para o Cronet na seção dependencies do arquivo build.gradle do módulo do app, conforme mostrado no exemplo abaixo:

    Groovy

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

    Kotlin

    dependencies {
       implementation("com.google.android.gms:play-services-cronet:18.0.1")
    }

Os objetos CronetEngine criados depois que você adiciona essa dependência usam o Cronet carregado do Google Play Services. Para evitar exceções inesperadas durante a criação de CronetEngine (como em dispositivos que exigem uma versão atualizada do Google Play Services), chame CronetProviderInstaller.installProvider(Context) antes de criar objetos CronetEngine.

Nos casos em que não é possível carregar a Cronet pelo Google Play Services, há uma implementação menos eficiente da API Cronet que pode ser usada. Para usar essa implementação substituta, dependa de org.chromium.net:cronet-fallback e chame new JavaCronetProvider(context).createBuilder().

Criar uma solicitação de rede

Nesta seção, mostramos como criar e enviar uma solicitação de rede usando a biblioteca Cronet. Depois de enviar a solicitação de rede, o app precisa processar a resposta da rede.

Criar e configurar uma instância do CronetEngine

A biblioteca fornece uma classe CronetEngine.Builder que pode ser usada para criar uma instância de CronetEngine. O exemplo a seguir mostra como criar um 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();

Use a classe Builder para configurar um objeto CronetEngine. Por exemplo, é possível fornecer opções como armazenamento em cache e compactação de dados. Para mais informações, consulte CronetEngine.Builder.

Fornecer uma implementação do callback da solicitação

Para fornecer uma implementação do callback, crie uma subclasse de UrlRequest.Callback e implemente os métodos abstratos necessários, conforme mostrado no exemplo abaixo:

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 for the read() method. The same buffer
        // with data is passed to the onReadCompleted() 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.
        byteBuffer?.clear()
        request?.read(byteBuffer)
    }

    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 for the read() method. The same buffer
    // with data is passed to the onReadCompleted() 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.
    byteBuffer.clear();
    request.read(byteBuffer);
  }

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

Criar um objeto Executor para gerenciar tarefas de rede

Use a classe Executor para executar tarefas de rede. Para receber uma instância de Executor, use um dos métodos estáticos da classe Executors que retornam um objeto Executor. O exemplo a seguir mostra como criar um objeto Executor usando o método newSingleThreadExecutor():

Kotlin

val executor: Executor = Executors.newSingleThreadExecutor()

Java

Executor executor = Executors.newSingleThreadExecutor();

Criar e configurar um objeto UrlRequest

Para criar a solicitação de rede, chame o método newUrlRequestBuilder() do CronetEngine transmitindo o URL de destino, uma instância da sua classe de callback e o objeto executor. O método newUrlRequestBuilder() retorna um objeto UrlRequest.Builder que pode ser usado para criar o objeto UrlRequest, conforme mostrado no exemplo a seguir:

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();

Use a classe Builder para configurar a instância de UrlRequest. Por exemplo, é possível especificar uma prioridade ou o verbo HTTP. Para mais informações, consulte UrlRequest.Builder.

Para iniciar a tarefa de rede, chame o método start() da solicitação:

Kotlin

request.start()

Java

request.start();

Siga as instruções nesta seção para criar e enviar uma solicitação de rede usando a Cronet. No entanto, para simplificar, o exemplo de implementação de UrlRequest.Callback apenas mostra uma mensagem no registro. A seção a seguir mostra como fornecer uma implementação de callback que oferece suporte a cenários mais úteis, como extrair dados da resposta e detectar uma falha na solicitação.

Processar a resposta da rede

Depois que você chama o método start(), a Cronet inicia o ciclo de vida da solicitação. Gerencie a solicitação durante o ciclo de vida especificando um callback. Para mais informações sobre o ciclo de vida, consulte Ciclo de vida da solicitação da Cronet. É possível especificar um callback criando uma subclasse de UrlRequest.Callback e implementando os seguintes métodos:

onRedirectReceived()

O Cronet invoca esse método quando o servidor emite um código de redirecionamento HTTP em resposta à solicitação original. Para seguir o redirecionamento para o novo destino, use o método followRedirect(). Caso contrário, use o método cancel(). O exemplo a seguir mostra como implementar o 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()

O Cronet invoca esse método quando o conjunto final de cabeçalhos é recebido. O Cronet invoca onResponseStarted() somente depois que todos os redirecionamentos são seguidos. O código abaixo mostra um exemplo de implementação do 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()

O Cronet invoca esse método sempre que parte do corpo da resposta é lida. O exemplo de código a seguir mostra como implementar o método e extrair o corpo da resposta:

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()

O Cronet invoca esse método quando a solicitação de rede é concluída com sucesso. O exemplo a seguir mostra como implementar o 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()

O Cronet invoca esse método se a solicitação falhar por qualquer motivo depois que o app chamar o método start(). O exemplo a seguir mostra como implementar o método e receber informações sobre o erro:

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()

O Cronet invoca esse método se a solicitação foi cancelada usando o método cancel(). Depois que o Cronet invoca onCanceled(), ele não invoca nenhum outro método da classe UrlRequest.Callback. É possível usar esse método para liberar recursos alocados para processar uma solicitação. O exemplo abaixo mostra como implementar o 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.
  ...
}