发送简单请求

了解如何使用 Cronet 库在您的 Android 应用中执行网络操作。Cronet 是 Chromium 网络堆栈,可作为库提供,供您在应用中使用。有关库功能的更多信息,请参阅 使用 Cronet 执行网络操作

在您的项目中设置库

请按照以下步骤在您的项目中添加对 Cronet 库的依赖项

  1. 验证 Android Studio 是否在您的项目的 settings.gradle 文件中包含对 Google Maven 存储库的引用,如下例所示

    Groovy

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

    Kotlin

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
    
  2. 在应用模块的 build.gradle 文件的 dependencies 部分中包含对 Google Play 服务客户端库 (Cronet) 的引用,如下例所示

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

添加此依赖项后创建的 CronetEngine 对象将使用从 Google Play 服务加载的 Cronet。在创建 CronetEngine 对象之前调用 CronetProviderInstaller.installProvider(Context),以防止在创建 CronetEngine 期间抛出意外异常,例如设备需要更新版本的 Google Play 服务。

在无法从 Google Play 服务加载 Cronet 的情况下,可以使用性能较低的 Cronet API 实现。要使用此回退实现,请依赖 org.chromium.net:cronet-fallback 并调用 new JavaCronetProvider(context).createBuilder()

创建网络请求

本部分介绍如何使用 Cronet 库创建和发送网络请求。发送网络请求后,您的应用应 处理网络响应

创建并配置 CronetEngine 实例

库提供了 CronetEngine.Builder 类,您可以使用该类创建 CronetEngine 实例。以下示例演示如何创建 CronetEngine 对象

Kotlin

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

Java

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

您可以使用 Builder 类来配置 CronetEngine 对象,例如,您可以提供缓存和数据压缩等选项。有关更多信息,请参阅 CronetEngine.Builder

提供请求回调的实现

要提供回调的实现,请创建 UrlRequest.Callback 的子类并实现所需的抽象方法,如下例所示

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

创建 Executor 对象来管理网络任务

您可以使用 Executor 类来执行网络任务。要获取 Executor 的实例,请使用 Executors 类的其中一个返回 Executor 对象的静态方法。以下示例展示了如何使用 newSingleThreadExecutor() 方法创建 Executor 对象

Kotlin

val executor: Executor = Executors.newSingleThreadExecutor()

Java

Executor executor = Executors.newSingleThreadExecutor();

创建并配置 UrlRequest 对象

要创建网络请求,请调用 newUrlRequestBuilder() 方法,该方法属于 CronetEngine,并传入目标 URL、回调类的实例和 executor 对象。 newUrlRequestBuilder() 方法会返回一个 UrlRequest.Builder 对象,您可以使用该对象来创建 UrlRequest 对象,如下例所示

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

您可以使用 Builder 类来配置 UrlRequest 的实例。例如,您可以指定优先级或 HTTP 方法。有关更多信息,请参阅 UrlRequest.Builder

要启动网络任务,请调用请求的 start() 方法

Kotlin

request.start()

Java

request.start();

通过遵循本节中的说明,您可以使用 Cronet 创建和发送网络请求。但是,为了简单起见,UrlRequest.Callback 的示例实现仅将消息打印到日志。下一节将展示如何提供支持更多有用场景的回调实现,例如从响应中提取数据和检测请求中的错误。

处理网络响应

调用 start() 方法后,Cronet 请求生命周期将开始。您的应用应通过指定回调来管理生命周期中的请求。要了解有关生命周期的更多信息,请参阅 Cronet 请求生命周期。您可以通过创建 UrlRequest.Callback 的子类并实现以下方法来指定回调

onRedirectReceived()

当服务器对原始请求发出 HTTP 重定向代码时调用。要遵循重定向到新目标,请使用 followRedirect() 方法。否则,请使用 cancel() 方法。以下示例展示了如何实现该方法

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

接收最终标头集时调用。只有在遵循所有重定向后才会调用 onResponseStarted() 方法。以下代码展示了该方法的示例实现

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

读取响应正文的一部分时调用。以下代码示例展示了如何实现该方法并提取响应正文

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

网络请求成功完成时调用。以下示例展示了如何实现该方法

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

如果请求在调用 start() 方法后因任何原因失败,则调用。以下示例展示了如何实现该方法并获取有关错误的信息

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

如果使用 cancel() 方法取消请求,则调用。调用后,将不会再调用 UrlRequest.Callback 类的任何其他方法。您可以使用此方法释放分配给处理请求的资源。以下示例展示了如何实现该方法

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.
  …
}