android 拦截webview加载url_Android WebView拦截且更改Url
最近做项目,遇到一个需求,因为是国际化项目,在新的国家部署机房,在该机房部署的H5域名和原来的不一样,要求客户端拦截H5,并更改Host。尝试了几种方案如下:重写WebView loadUrl()方法,在该方法中更改Url。@Overridepublic void loadUrl(String url) {......url = convertUrl(url);......// 必须调用super
最近做项目,遇到一个需求,因为是国际化项目,在新的国家部署机房,在该机房部署的H5域名和原来的不一样,要求客户端拦截H5,并更改Host。
尝试了几种方案如下:
重写WebView loadUrl()方法,在该方法中更改Url。
@Override
public void loadUrl(String url) {
......
url = convertUrl(url);
......
// 必须调用super,让系统继续加载新的url
super.loadUrl(url);
}
复制代码
上面的方案,在测试中发现,H5页面中有跳转二级页面时,没有走。
重写WebViewClient shouldOverrideUrlLoading()方法
先来看下源码的注释
/**
* Give the host application a chance to take over the control when a new
* url is about to be loaded in the current WebView. If WebViewClient is not
* provided, by default WebView will ask Activity Manager to choose the
* proper handler for the url. If WebViewClient is provided, return true
* means the host application handles the url, while return false means the
* current WebView handles the url.
* This method is not called for requests using the POST "method".
*
* @param view The WebView that is initiating the callback.
* @param url The url to be loaded.
* @return True if the host application wants to leave the current WebView
* and handle the url itself, otherwise return false.
* @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
* shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
*/
@Deprecated
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
/**
* Give the host application a chance to take over the control when a new
* url is about to be loaded in the current WebView. If WebViewClient is not
* provided, by default WebView will ask Activity Manager to choose the
* proper handler for the url. If WebViewClient is provided, return true
* means the host application handles the url, while return false means the
* current WebView handles the url.
*
*
Notes:
*
*
This method is not called for requests using the POST "method".*
This method is also called for subframes with non-http schemes, thus it is* strongly disadvised to unconditionally call {@link WebView#loadUrl(String)}
* with the request's url from inside the method and then return true,
* as this will make WebView to attempt loading a non-http url, and thus fail.
*
*
*
* @param view The WebView that is initiating the callback.
* @param request Object containing the details of the request.
* @return True if the host application wants to leave the current WebView
* and handle the url itself, otherwise return false.
*/
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
复制代码
如果开发没有设置WebViewClient,WebView会让Activity Manager选择合适的处理方法(可能使用浏览器)。如果设置了WebViewClient,该方法返回true,则主程序处理改url,如果返回false,则当前WebView处理,即系统默认处理。(不会执行WebView的loadUrl方法)
最开始的想法是在shouldOverrideUrlLoading()方法更改url,不过发现,这里可以拦截到,但更改后的url,无法让系统默认加载。只能主程序显示调用加载。
@Override
public boolean shouldOverrideUrlLoading(final String url) {
if (isInterceptUrlLoading(url)) {
// 重点处理二级页面跳转的情况
// 如果直接返回false,会由系统默认加载,则无法改变url,且也不会走到loadUrl中,无法在该方法中更改url
getWebView().loadUrl(url);
return true;
}
return false;
}
复制代码寻找其他更优解法
上面方法2的解法,会改变原来url的加载方式,所以找了找有没有其他更好的办法。
重写WebViewClient的shouldInterceptRequest方法。
/**
* Notify the host application of a resource request and allow the
* application to return the data. If the return value is null, the WebView
* will continue to load the resource as usual. Otherwise, the return
* response and data will be used. NOTE: This method is called on a thread
* other than the UI thread so clients should exercise caution
* when accessing private data or the view system.
*
* @param view The {@link android.webkit.WebView} that is requesting the
* resource.
* @param url The raw url of the resource.
* @return A {@link android.webkit.WebResourceResponse} containing the
* response information or null if the WebView should load the
* resource itself.
* @deprecated Use {@link #shouldInterceptRequest(WebView, WebResourceRequest)
* shouldInterceptRequest(WebView, WebResourceRequest)} instead.
*/
@Deprecated
public WebResourceResponse shouldInterceptRequest(WebView view,
String url) {
return null;
}
/**
* Notify the host application of a resource request and allow the
* application to return the data. If the return value is null, the WebView
* will continue to load the resource as usual. Otherwise, the return
* response and data will be used. NOTE: This method is called on a thread
* other than the UI thread so clients should exercise caution
* when accessing private data or the view system.
*
* @param view The {@link android.webkit.WebView} that is requesting the
* resource.
* @param request Object containing the details of the request.
* @return A {@link android.webkit.WebResourceResponse} containing the
* response information or null if the WebView should load the
* resource itself.
*/
public WebResourceResponse shouldInterceptRequest(WebView view,
WebResourceRequest request) {
return shouldInterceptRequest(view, request.getUrl().toString());
}
复制代码
该方法可以拦截所有请求,除了Html的页面,其他资源js、css都会拦截到。
通过注释,如果返回null,则WebView还是会默认加载原来的url,需要自己创建WebResourceResponse。
可以在此处做离线资源的加载,但不适合只更改url,因为无法创建WebResourceResponse。
结论
最后使用方法1和方法2的结合来处理的。

关于找一找教程网
本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[Android WebView拦截且更改Url]http://www.zyiz.net/tech/detail-131790.html
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)