场景一:Api接口请求场景
选用阿里云HttpDns服务,利用HttpDns解析获得ip后进行ip直连的方法。
当前项目中网络数据请求框架采用Okhttp+Retrofit组合,OkHttp暴露了一个Dns接口,通过自定义一个Dns解析器替换系统默认Dns实现。若获取IP失败则选用默认Dns解析。
场景二:WebView业务场景
选用阿里云HttpDns服务,主要实现方案同样是IP直连。
1.对WebView加载的Url进行拦截:WebView提供了setWebViewClient接口对网络请求进行拦截,通过重载WebViewClient中的shouldInterceptRequest方法,我们可以拦截到所有的网络请求。
2.将拦截到的请求域名替换成ip,添加原有头部信息,设置Http请求头Host域;
3.如果拦截到的请求是HTTPS请求,需要进行证书校验,如果请求涉及到SNI场景,需要自定义SSLSocket;
4.如果服务端返回重定向,此时需要判断原有请求中是否含有cookie;
5.根据拦截的头信息获取MIME类型以及编码类型来判断本次请求是否拦截。
参考Android Webview + HttpDns最佳实践。
注意事项
1.阿里云HttpDns服务提供预解析功能,可以将常用域名加入预解析列表中。
httpDnsService.setPreResolveHosts(new ArrayList<>(Arrays.asList("app.xxxx.com")));
2.WebView可用场景
前提条件:
- API Level >= 21
- GET请求
- 可以获取到MIME类型以及编码信息请求或是可以获取到MIME类型的二进制文件请求
可用场景:
- 普通HTTP请求
- HTTPS请求
- SNI请求
- HTTP报头中不含cookie的重定向请求。
3.不可用场景
- API Level < 21的设备
- POST请求
- 无法获取到MIME类型的请求
- 无法获取到编码的非二进制文件请求
网友评论