一种排查webview的兼容性问题的方法

背景是这样的,我们的应用内嵌了webview,测试同学配测试连接的时候,在某部手机上,应用闪退了。
我就用了系统的webview,没做什么特殊处理,应该是网页的问题,但是具体是什么问题呢?
上午刚好有一点时间,所以我做了一下问题定位和排查,我是这样排查的:

step 1 继承 WebViewClient,查看有哪些HTTP请求,把一些可以的直接返回空

// setWebViewClient(new YeshenWebViewClient());
private final class YeshenWebViewClient extends WebViewClient {
  ...
  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  @Nullable
  @Override
  public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
      if (VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && request != null
              && request.getUrl() != null && request.getUrl().getHost() != null) {
          String url = request.getUrl().toString();
          WebResourceResponse response = fetch(url);
          if (response != null) return response;
      }
      return super.shouldInterceptRequest(view, request);
  }

  @Nullable
  @Override
  public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
      WebResourceResponse response = fetch(url);
      if (response != null) return response;
      return super.shouldInterceptRequest(view, url);
  }

  private WebResourceResponse fetch(String url) {
      if (url.equals("${可疑连接}")) {
          return new WebResourceResponse("text/html", "utf-8",
                  new ByteArrayInputStream("".getBytes()));
      }
      Log.e("Yeshen", url);
      return null;
  }
}

在这个场景下,其实实际问题是,https://www.163.com 在魅族note2手机(Mozilla/5.0 (Linux; Android 5.1; M571C Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.2214.127 Mobile Safari/537.36)上,在用原生webview加载是,会使应用闪退。

所以我把 https://www.163.com 的所以http请求都打印了出来,一个个试,看看那个HTTP请求比较可疑。

最后我还是试出来了,只要屏蔽了这个连接,就不会闪退:
https://static.ws.126.net/163/wap/f2e/milk_index/index.e7d25e8a.js

step 2 替换出错的js请求

  1. 把上述文件保存下来
  2. 做一下反序列化: https://beautifier.io/
  3. 保存在 /app/src/main/assets 目录下
  4. 在代码中这样读取
private WebResourceResponse fetch(String url) {
    if (url.equals("https://static.ws.126.net/163/wap/f2e/milk_index/index.e7d25e8a.js")) {
        return new WebResourceResponse("text/html", "utf-8",
                new ByteArrayInputStream(readJsContent(getContext()).getBytes()));
    }
    Log.e("Yeshen", url);
    return null;
}

final String readJsContent(Context context) {
    StringBuilder js = new StringBuilder();
    try {
        InputStream is = context.getAssets().open("milk_index.js");
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null) {
            js.append(line);
        }
        is.close();
    } catch (Exception e) {/*ignore it*/
    }
    return js.toString();
}

step 3 阅读代码,打日志确定出问题的位置

可以这样打日志

console.log("tag #12");

我尝试了许久,在上面1.2万行代码中各种打日志。
打了许久的日志,我发现程序是有入口的,入口在 ./app/src/main.js

出错点也在这个里面,出错的主要是这三行代码

"serviceWorker" in navigator && navigator.serviceWorker.register("/service-worker-index.js").catch(function (e) {
  return console.log(e)
}),

step 4 尝试复现问题

我用手机连接电脑,打开了调试模式,在chrome浏览器中,打开了 chrome://inspect
在其中输入了这样一行代码:

navigator.serviceWorker.register("")

应用如愿闪退。

玩~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值