Отправить простой запрос

Узнайте, как использовать библиотеку Cronet для выполнения сетевых операций в приложении Android. Cronet — это сетевой стек Chromium, доступный в виде библиотеки, которую вы можете использовать в своих приложениях. Дополнительные сведения о функциях библиотеки см. в разделе «Выполнение сетевых операций с помощью Cronet» .

Настройте библиотеку в своем проекте

Выполните следующие действия, чтобы добавить зависимость к библиотеке Cronet в вашем проекте:

  1. Убедитесь, что Android Studio включила ссылку на репозиторий Google Maven в файл settings.gradle вашего проекта, как показано в следующем примере:

    dependencyResolutionManagement {
       
    ...
       repositories
    {
           
    ...
           google
    ()
       
    }
    }
    dependencyResolutionManagement {
       
    ...
       repositories
    {
           
    ...
           google
    ()
       
    }
    }
  2. Включите ссылку на клиентскую библиотеку сервисов Google Play для Cronet в раздел dependencies файла build.gradle вашего модуля приложения, как показано в следующем примере:

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

Объекты CronetEngine , созданные после добавления этой зависимости, будут использовать Cronet, загруженный из сервисов Google Play. Вызовите CronetProviderInstaller.installProvider(Context) перед созданием объектов CronetEngine , чтобы предотвратить возникновение неожиданных исключений во время создания CronetEngine из-за таких ошибок, как устройства, требующие обновленной версии сервисов Google Play.

В тех случаях, когда Cronet невозможно загрузить из сервисов Google Play, можно использовать менее производительную реализацию API Cronet. Чтобы использовать эту резервную реализацию, используйте org.chromium.net:cronet-fallback и вызовите new JavaCronetProvider(context).createBuilder() .

Создать сетевой запрос

В этом разделе показано, как создать и отправить сетевой запрос с помощью библиотеки Cronet. После отправки сетевого запроса ваше приложение должно обработать ответ сети .

Создайте и настройте экземпляр CronetEngine.

Библиотека предоставляет класс CronetEngine.Builder , который можно использовать для создания экземпляра CronetEngine . В следующем примере показано, как создать объект CronetEngine :

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

Вы можете использовать класс Builder для настройки объекта CronetEngine , например, вы можете предоставить такие параметры, как кэширование и сжатие данных. Для получения дополнительной информации см. CronetEngine.Builder .

Предоставить реализацию обратного вызова запроса

Чтобы обеспечить реализацию обратного вызова, создайте подкласс UrlRequest.Callback и реализуйте необходимые абстрактные методы, как показано в следующем примере:

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.")
   
}
}
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.");
 
}
}

Создайте объект «Исполнитель» для управления сетевыми задачами.

Вы можете использовать класс Executor для выполнения сетевых задач. Чтобы получить экземпляр Executor , используйте один из статических методов класса Executors , которые возвращают объект Executor . В следующем примере показано, как создать объект Executor с помощью метода newSingleThreadExecutor() :

val executor: Executor = Executors.newSingleThreadExecutor()
Executor executor = Executors.newSingleThreadExecutor();

Создайте и настройте объект UrlRequest.

Чтобы создать сетевой запрос, вызовите метод newUrlRequestBuilder() CronetEngine передав целевой URL, экземпляр вашего класса обратного вызова и объект исполнителя. Метод newUrlRequestBuilder() возвращает объект UrlRequest.Builder , который можно использовать для создания объекта UrlRequest , как показано в следующем примере:

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

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

UrlRequest request = requestBuilder.build();

Вы можете использовать класс Builder для настройки экземпляра UrlRequest . Например, вы можете указать приоритет или команду HTTP. Дополнительные сведения см. в UrlRequest.Builder .

Чтобы запустить сетевую задачу, вызовите метод start() запроса:

request.start()
request.start();

Следуя инструкциям в этом разделе, вы сможете создать и отправить сетевой запрос с помощью Cronet. Однако для простоты пример реализации UrlRequest.Callback печатает только сообщение в журнал. В следующем разделе показано, как обеспечить реализацию обратного вызова, которая поддерживает более полезные сценарии, такие как извлечение данных из ответа и обнаружение сбоя в запросе.

Обработка ответа сети

Как только вы вызываете метод start() , запускается жизненный цикл запроса Cronet. Ваше приложение должно управлять запросом в течение жизненного цикла, указав обратный вызов. Дополнительные сведения о жизненном цикле см. в разделе Жизненный цикл запроса Cronet . Вы можете указать обратный вызов, создав подкласс UrlRequest.Callback и реализовав следующие методы:

onRedirectReceived()

Вызывается, когда сервер выдает код перенаправления HTTP в ответ на исходный запрос. Чтобы следовать за перенаправлением в новый пункт назначения, используйте метод followRedirect() . В противном случае используйте метод cancel() . В следующем примере показано, как реализовать метод:

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

 
if (shouldFollow) {
      request
?.followRedirect()
 
} else {
      request
?.cancel()
 
}
}
@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()

Вызывается при получении окончательного набора заголовков. Метод onResponseStarted() вызывается только после выполнения всех перенаправлений. В следующем коде показан пример реализации метода:

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

Вызывается всякий раз, когда считывается часть тела ответа. В следующем примере кода показано, как реализовать метод и извлечь тело ответа:

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

Вызывается при успешном завершении сетевого запроса. В следующем примере показано, как реализовать метод:

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

Вызывается, если запрос по какой-либо причине не выполнен после вызова метода start() . В следующем примере показано, как реализовать метод и получить информацию об ошибке:

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

Вызывается, если запрос был отменен с помощью метода cancel() . После вызова никакие другие методы класса UrlRequest.Callback не вызываются. Вы можете использовать этот метод, чтобы освободить ресурсы, выделенные для обработки запроса. В следующем примере показано, как реализовать метод:

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

}