发送简单请求

本文介绍了如何使用 Cronet 库在您的 Android 应用中执行网络操作。Cronet 是 Chromium 网络堆栈,可作为库供您在应用中使用。如需详细了解该库的功能,请参阅使用 Cronet 执行网络操作

在您的项目中设置库

要在您的项目中为 Cronet 库添加依赖项,请按以下步骤操作:

  1. 在项目的顶层 build.gradle 文件中验证 Android Studio 是否包含对 Google 的 Maven 代码库的引用,如以下示例所示:

    allprojects {
            repositories {
                ...
                google()
            }
        }
        
  2. 找到应用模块的 build.gradle 文件,在 dependencies 部分中添加对 Cronet 的 Google Play 服务客户端库的引用,如以下示例所示:

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

    添加此依赖项后创建的 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 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.");
      }
    }
    

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

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

Kotlin

    val executor: Executor = Executors.newSingleThreadExecutor()
    

Java

    Executor executor = Executors.newSingleThreadExecutor();
    

创建并配置 UrlRequest 对象

要创建网络请求,请调用 CronetEnginenewUrlRequestBuilder() 方法,并传递目标网址、回调类的实例以及 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.
      …
    }