VasSonic之流式拦截

VasSonic之流式拦截

VasSonic框架用到了流式拦截和增量更新技术,下面只简单介绍流式拦截,详细参考:https://github.com/Tencent/VasSonic/wiki
VasSonic之流式拦截_第1张图片

一)传统H5页面打开缓慢的原因?

1.打开一个H5页面首先需要初始化WebView内核和渲染组件(冷启动耗时200~500ms,冷启动过程中网络处于空等状态)
2.完成初始化后,WebView在CDN上请求Html页面,数据回来后再对DOM进行操作更新

二)Sonic框架如何优化Webview初始化过程中网络空等问题?

针对网络空闲问题,Sonic做了并行请求,通过Native建立http链接获取html数据,充分利用这段空闲时间。最理想的情况是html数据下载完成,Webview还没初始化好,等Webview初始化完成直接加载本地html;当Webview初始化完成,html还没下载完,这时就要提到流式拦截技术了
VasSonic之流式拦截_第2张图片

三)流式拦截如何实现?

将Html已读流(memStream)和未读流(netStream)桥接成SonicSessionStream,SonicSessionStream继承InputStream并重写read方法,SonicSessionStream包装成WebResourceResponse对象,通过webview拦截接口shouldInterceptRequest将WebResourceResponse回传给webview,SonicSessionStream代码如下:

public class SonicSessionStream extends InputStream{
  // 未加载HTML流
  private BufferedInputStream netStream;
  // 已加载HTML流
  private BufferedInputStream memStream;

  // 省略非关键代码
  @Override
  public synchronized int read() throws IOException {

    int c = -1;

    try {
      if (null != memStream && !memStreamReadComplete) {
        c = memStream.read();
      }

      if (-1 == c) {
        memStreamReadComplete = true;
        if (null != netStream && !netStreamReadComplete) {
          c = netStream.read();
          if (-1 != c) {
            outputStream.write(c);
          } else {
            netStreamReadComplete = true;
          }
        }
      }
    } catch (Throwable e) {
      Log.e(TAG, "read error:" + e.getMessage());
      if (e instanceof IOException) {
        throw e;
      } else {//Turn all exceptions to IO exceptions to prevent scenes that the kernel can not capture
        throw new IOException(e);
      }
    }

    return c;
  }
  // 省略非关键代码
}

在webview拦截接口shouldInterceptRequest中处理mSonicSessionStream,代码如下:

mWebView.setWebViewClient(new WebViewClient() {

      @Override
      public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        if (mMallHtmlStream != null && isInterceptByWebView.get() && isMatchCurrentUrl(url)) {
          String mime = MallHtmlUtils.getMime(url);
          return new WebResourceResponse(mime, "utf-8", mSonicSessionStream);
        }
        return super.shouldInterceptRequest(view, url);
      }
    });

核心思想是充分利用webview初始化的时间,由native建立http链接请求HTML资源,在webview初始化完成前,尽可能的多请求HTML数据,等webview完成初始化立即将HTML提供给Webview渲染。

你可能感兴趣的:(android)