android webview首次加载速度过慢解决

2019-08-14  本文已影响0人  走在冷风中吧

前言:

在客户端开发过程中, 我们难免有一些页面需要配合h5去展示, android中使用webview去加载h5页面, 但是使用h5页面去加载的时候, 明显体验要比原生差很多, 尤其是第一次请求网页时.

这是因为h5页面在加载时, 需要从服务器获取各种资源,比如: 图片, js文件, css文件, 自身api等... 相比而言, 客户端的资源都是静态的, 我们通常只是去请求个自己的api, 用户体验会好很多.

为了解决这个问题, 我们可以采取以下方案:

注意: 这种方法比较适合于一些大型首页, 相当一部分的资源文件如图片和js是不会发生变动的. 不过即使发生变动我们也会有应对策略, 后续会提到~


方案: 客户端将静态资源包预置到apk内, 在webview内进行资源拦截和替换

步骤:

  1. 将前端需要预先加载资源放置到assert目录中
  2. 使用webview进行网络资源拦截
  3. 使用assert下的资源包将resource进行动态替换

代码实现:

mWebView.setWebViewClient(new WebViewClient() {
              @Nullable
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
//这里我们拦截资源名包含gjhh-600x400.jpg的请求
                if(request.getUrl().toString().contains("gjhh-600x400.jpg")){
// 我先使用本地的一个drawable测试替换, 在实际操作中我们也可以将资源包统一放置assert目录下进行管理
                    Drawable drawable = getResources().getDrawable(R.drawable.base_app_icon);
                    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                            drawable.getIntrinsicHeight(),
                            Bitmap.Config.RGB_565);
                    Canvas canvas = new Canvas(bitmap);
                    drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
                    drawable.draw(canvas);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.PNG,100,baos);
                    InputStream is = new ByteArrayInputStream(baos.toByteArray());
//使用本地的资源包response
                    return new WebResourceResponse("image/png","utf-8",is);
                }

                return super.shouldInterceptRequest(view, request);
            }
}
问题: 如果资源需要发生改变, 更新, 怎么办呢?

如果我们没有预置web的这些资源的话, 他们的更新极其容易, 客户端可以撒手不管. 但是当把资源放入到客户端时, 我们应该如何做到及时的更新呢?
有三种解决方案:

1. 客户端发版 (这是最简单粗暴的做法)

客户端更新新的资源文件之后, 发布新版本

2. 采用热更新的方式动态下发新的资源包

为了避免强制升级或者发布新版本后下载不及时问题, 可以采用热更新的方式做资源文件的替换, 大家采用自己喜欢的热更新方式即可

3. 当有资源变更时, 服务器下发资源给客户端, 客户端和服务器需各自持有一个资源的唯一码来用作校验

采用这种方法:
1.首先客户端会持有当前最新的资源包, 以及与服务器约定好的初始资源唯一码;
2.客户端在每次启动的时候, 先去提交给服务器唯一码及资源包名, 由服务器判断当前资源是否为最新, (此处借鉴http缓存处理--Etag对比)
如果是最新则进行将assert下资源解压值指定目录, 当webview请求数据资源时, 从该目录进行匹配替换.
如果不是最新资源, 服务器下发最新的资源包及资源的id等信息, 客户端至相同位置进行覆盖, 保证webview取到最新的资源

在这个处理过程中, 我们还需要考虑资源包会被系统清理删除等问题, 以及资源包下载是否完整等.

以上还未进行实践, 可能有错误之处, 先做笔记后续工作用到会加以改进!
End..

上一篇 下一篇

猜你喜欢

热点阅读