DevSupport

Chromium内核原理之cronet独立化

2019-02-14  本文已影响52人  码上就说

《Chromium内核原理之blink内核工作解密》
《Chromium内核原理之多进程架构》
《Chromium内核原理之进程间通信(IPC)》
《Chromium内核原理之网络栈》
《Chromium内核原理之网络栈HTTP Cache》
《Chromium内核原理之Preconnect》
《Chromium内核原理之Prerender》
《Chromium内核原理之cronet独立化》

1.Cronet介绍
2.Cronet编译
3.Cronet使用

3.1 使用Cronet发送request
3.2 Cronet request 生命周期

4.Cronet源码架构分析

1.Cronet介绍

Cronet是作为库提供给Android应用程序的Chromium网络堆栈。 Cronet利用多种技术来减少延迟并提高应用程序需要工作的网络请求的吞吐量。

Cronet Library每天处理数百万人使用的应用程序请求,例如YouTube,Google App,Google Photos和Maps - Navigation&Transit。

Cronet具有以下特点:

2.Cronet编译

参考:https://chromium.googlesource.com/chromium/src/+/master/components/cronet/build_instructions.md?autodive=0%2F%2F

3.Cronet使用

3.1 使用Cronet发送request

如果要使用Cronet框架,需要按照下面的步骤来实现其功能:

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

注意:
建议只创建一个CronetEngine实例。单个实例可以发送多个异步请求。此外,存储目录不支持多个CronetEngine实例的并发访问。有关更多信息,请参阅setStoragePath()。

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

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

  @Override
  public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
    android.util.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) {
    android.util.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) {
    android.util.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) {
    android.util.Log.i(TAG, "onSucceeded method called.");
  }
}
Executor executor = Executors.newSingleThreadExecutor();
UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder(
        "https://www.example.com", new MyUrlRequestCallback(), executor);

UrlRequest request = requestBuilder.build();

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

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

request.start();

按照本节中的说明,您可以使用Cronet创建和发送网络请求。但是,为简单起见,UrlRequest.Callback的示例实现仅将消息输出到日志。以下部分显示如何提供支持更多有用方案的回调实现,例如从响应中提取数据和检测请求中的故障。


onRedirectReceived()
当服务器发出HTTP重定向代码以响应原始请求时调用。要跟随重定向到新目标,请使用followRedirect()方法。否则使用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
public void onResponseStarted(UrlRequest request, UrlResponseInfo responseInfo) {
  int httpStatusCode = responseInfo.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);
  }
  mResponseHeaders = responseInfo.getAllHeaders();
}

从Cronet的角度来看,状态代码4xx和5xx不被视为错误。您仍应尝试使用read()方法读取响应,因为它可能包含一些数据。您也可以使用cancel()方法取消请求。这些操作可确保请求进入最终状态。


onReadCompleted()
只要读取了部分响应主体,就会调用它。以下代码示例演示如何实现该方法并提取响应正文:

@Override
public void onReadCompleted(UrlRequest request, UrlResponseInfo responseInfo, 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
public void onSucceeded(UrlRequest request, UrlResponseInfo responseInfo) {
  // The request has completed successfully.
}

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

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

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

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

3.2 Cronet request 生命周期

使用Cronet Library创建的网络请求由UrlRequest类表示。以下概念对于理解UrlRequest生命周期非常重要:

States:
状态是请求在特定时间处于的特定条件。使用Cronet Library创建的UrlRequest对象在其生命周期中移动通过不同的状态。请求生命周期包括初始状态,以及多个过渡状态和最终状态。

UrlRequest methods:
客户端可以根据状态调用UrlRequest对象上的特定方法。这些方法将请求从一个状态移动到另一个状态。

Callback methods:
通过实现UrlRequest.Callback类的方法,您的应用可以接收有关请求进度的更新。您可以实现回调方法来调用UrlRequest对象的方法,该方法将生命周期从一个状态转移到另一个状态。

下面描述了UrlRequest的生命周期:

  • 使用followRedirect()跟随重定向。此方法将请求恢复为已启动状态。
  • 使用cancel()取消请求。此方法将请求带到onCanceled()方法,其中应用程序可以在请求移动到Canceled final状态之前执行其他操作。
  • 读取response是成功的,但有更多的数据可用。调用onReadCompleted()并且请求再次处于Waiting for read()状态。应用程序应再次调用read()方法以继续读取响应正文。应用程序也可以使用cancel()方法停止读取请求。
  • 读取response是成功的,没有更多的数据可用。调用onSucceeded()方法,请求现在处于Succeeded最终状态。
  • 读取response失败了。调用onFailed方法,请求的最终状态现在为Failed。


4.Cronet源码架构分析

核心的API可以参考:https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/package-summary

上一篇下一篇

猜你喜欢

热点阅读